OPENCOURSE바이브 코딩으로 배우는 Flutter 첫걸음

챕터 4 / 5

상태로 움직이는 화면

예상 70분 · 소단원 3 · 앞 챕터 3 위젯 트리 이해하기에서 이어져요

영상을 준비하고 있어요

브라우저에서 조립해 재생해요 — 보통 몇 초면 끝나요

4.1상태가 뭐예요

앞선 3장 실습에서 우리는 '눌러 보세요' 버튼을 화면에 올렸어요. 화면의 그 '눌러 보세요' 버튼을 한번 눌러 보세요. 눌러 보면 알겠지만, 지금은 눌러도 아무 일도 일어나지 않아요. 지금까지 만든 화면은 사진처럼 멈춰 있었거든요. 코드에 적힌 그대로 늘 같은 모습만 보여 주니, 이런 화면은 '정지 화면'이라고 부를 수 있어요.

그런데 우리가 매일 쓰는 앱은 달라요. 예를 들어 버튼을 누르면 좋아요 숫자가 올라가고, 알림 스위치를 켜면 화면 표시가 바뀌죠. 화면이 이렇게 반응하려면, 앱이 먼저 무언가를 기억하고 있어야 해요. 지금까지 몇 번 눌렸는지 기억해야, 다음에 어떤 숫자를 보여 줄지 알 수 있으니까요.

이 '화면이 기억하는 값'을 상태라고 불러요. 엘리베이터를 떠올려 보세요. 문 위의 숫자는 지금 몇 층인지 알려 줘요. 엘리베이터가 다른 층으로 가면 문 위의 숫자도 바뀌죠. 여기서 '현재 층'이라는 값이 상태예요. 문 위의 숫자 표시는 그 값을 보여 준 결과고요.

앱도 엘리베이터처럼 기억하는 값을 갖고 있어요. 버튼을 누른 횟수, 입력창에 적은 이름, 알림이 켜져 있는지 꺼져 있는지가 전부 그런 값이에요. 기억하는 값의 종류만 다를 뿐, 전부 상태예요.

여기서 관점을 한번 바꿔 볼게요. 화면은 상태를 그린 결과예요. 지금 '안녕, Flutter!'가 보이는 건, 코드에 그 글자가 적혀 있기 때문이에요. 그렇다면 화면이 기억하는 값이 바뀌면 어떻게 될까요? 값이 바뀌면 화면도 따라 바뀌어야 해요. 누른 횟수가 0에서 1이 되면, 화면의 숫자도 1로 다시 그려져야 하죠. 값 따로, 화면 따로면 앱이 거짓말을 하는 셈이에요.

정리하면, 버튼이 반응하려면 두 가지가 필요해요. 첫째는 눌렀을 때 값을 바꾸는 일이에요. 둘째는 바뀐 값으로 화면을 다시 그리는 일이에요. 지금 우리 버튼에는 값 바꾸기도, 다시 그리기도 없어요. 그래서 눌러도 조용했던 거예요. 그럼 이 두 가지는 AI에게 어떻게 부탁하면 될까요?

4.2setState 한 걸음

4.1에서 숙제가 하나 남았어요. 값을 바꾸는 것만으로는 부족하고, 화면도 다시 그려야 한다는 것이었죠. Flutter는 값 바꾸기와 다시 그리기, 이 두 가지를 한 번에 해 주는 도구를 준비해 두었어요. 이름은 setState예요.

그 전에 만나 둘 이름이 하나 있어요. 함수는 이름을 붙여 둔 일 묶음이고, 그 이름을 부르면 일이 실행돼요. 모든 위젯에는 자기 모습을 그리는 build라는 함수가 있어요. build는 "내 모습을 그려 줘"라고 부탁하면 실행되는 그리기 함수예요. 우리가 지금까지 본 화면은 전부 build가 그린 결과였어요.

이제 핵심 문장이에요. setState를 부르면 상태가 바뀌고, Flutter가 build를 다시 실행해서 바뀐 값으로 화면을 다시 그려요. 이 한 문장이 이번 챕터의 심장이에요. 값 바꾸기와 다시 그리기라는 두 숙제가 setState 한 줄로 함께 풀려요.

흐름을 그림으로 보면 이래요. 손가락이 버튼을 탭해요. 그 탭이 setState를 부르는 코드를 실행해요. setState가 불리면 Flutter가 build를 다시 실행해요. 새 화면이 나타나요.

setState가 화면을 다시 그리는 흐름. 버튼을 탭하면 setState가 상태를 바꾸고, build가 다시 실행되어 새 화면이 나타나는 네 단계가 화살표로 이어져 있다.
그림 1 — setState에서 새 화면까지의 인과 사슬을 시각화한다

코드에서는 이렇게 생겼어요.

int count = 0;

setState(() {
  count = count + 1;
});

위 코드는 count라는 이름의 상태 변수(값을 기억해 두는 자리)를 만들고, setState 안에서 그 값에 1을 더해요. 그러면 Flutter가 알아서 화면을 다시 그려요.

외울 이름은 상태 변수와 setState, 둘뿐이에요. 코드는 AI가 써 줘요. 우리는 받은 코드에 이 흐름이 들어 있는지 확인하면 돼요. 받은 코드에서 볼 곳은 상태 변수가 있는지, 값을 바꾸는 자리가 setState 안인지 두 곳이에요. 그 두 곳만 보면 충분해요.

4.3실습 — 숫자 세기 버튼

이번에는 3장에서 만든 '눌러 보세요' 버튼을 진짜로 일하게 해 볼 거예요. 버튼이 눌린 횟수를 화면에 보여 주는 앱이에요. 순서는 3장 습관 그대로예요. 그림 먼저, 부탁은 그다음이에요.

  1. 트리를 그려요. 3장 화면에서 인사말이 있던 자리에 숫자 Text를 놓아요. 종이에 이렇게 적어 보세요.

    Column
    ├── Text ("0")   ← 눌릴 때마다 바뀌는 부분
    └── Button ("눌러 보세요")
    

    바뀌는 위젯이 어디인지 표시해 두는 게 핵심이에요. 숫자 Text 하나만 바뀌고, 버튼은 그대로예요.

  2. AI에게 보낼 프롬프트를 써요. 그림을 보면서 부탁할 말을 먼저 직접 적어 보세요. 다 썼으면 아래 예시와 비교해 보세요.

    가운데 숫자가 보이고, 버튼을 누를 때마다 1씩 늘어나게 해 줘. 숫자는 0부터 시작해.

  3. 받은 코드를 확인해요. 받은 코드를 전부 읽을 필요는 없어요. 아래 두 가지만 찾으면 돼요.

    • 숫자를 기억하는 상태 변수가 있나요? 보통 count처럼 뜻이 보이는 이름을 써요.
    • 버튼을 눌렀을 때 실행되는 코드 안에 setState가 있나요? 4.2에서 본 대로, setState가 있어야 화면이 다시 그려져요.
  4. DartPad에서 실행해요. DartPad에서 실행하고 버튼을 세 번 눌러 보세요. 숫자가 0, 1, 2, 3으로 바뀌면 성공이에요.

잘 안 되는 경우가 하나 있어요. 눌러도 화면의 숫자가 그대로일 때예요. setState 없이 값만 바꿔서, 값은 늘어도 화면이 다시 그려지지 않은 거예요. setState를 빼먹은 이런 경우에는 빨간 오류 문구도 나오지 않아서 더 헷갈려요. AI에게 이렇게 부탁하세요. "숫자를 바꾸는 부분을 setState로 감싸 줘." 다시 실행하면 숫자가 움직일 거예요.

오늘 여러분의 앱이 처음으로 손끝에 반응했어요. 축하해요.