[플러터] 13. Flutter 상태 관리와 리빌드 최적화

백하림's avatar
May 29, 2025
[플러터] 13. Flutter 상태 관리와 리빌드 최적화

1. 상태 (State, 객체의 상태)

  • 의미: 객체가 현재 가지고 있는 데이터나 속성 값.
  • 예시: 버튼 위젯의 isPressed, color, enabled 값 등이 상태임.
  • 역할: 상태가 바뀌면 그걸 기준으로 UI도 다시 그려져야 함.

2. 불변 상태 / 변하는 상태

  • 불변 상태: 한 번 설정되면 바뀌지 않음 (const, final 같은 성질)
    • 예: 사용자 이름 텍스트 → 바뀔 일 없음
  • 변하는 상태: 사용자 입력, 클릭 등으로 값이 달라짐
    • 예: 좋아요 버튼의 눌림 여부

3. 상태가 변할 때 그림이 reload됨 (Stateless vs Stateful)

  • StatelessWidget: 상태는 있지만 불변 → 상태가 바뀌면 새로 만들기 전까진 반영 불가
  • StatefulWidget: 상태를 가진 객체(State)를 따로 두고, setState() 호출 시 해당 위젯만 다시 그림

4. context (문맥, 도화지)

  • 의미: 현재 위젯이 어디에 위치해 있는지, 화면 구조 속에서의 위치를 알려주는 정보
  • 비유: 네비게이션 앱에서 “지금 어디에 있냐”를 말해주는 위치 정보
  • 활용: context를 통해 Theme, Scaffold, Navigator 등을 찾아서 쓸 수 있음

5. const

  • 역할: 불변 위젯을 생성. 내용이 절대 변하지 않음.
  • 장점:
    • 위젯 트리 캐싱 가능 → 리빌드할 때 성능 향상
    • 불필요한 재생성 방지
  • 주의: 내부에 전달되는 값도 const여야 진짜 const 위젯이 됨

6. 위젯 트리와 비용

  • 위젯 트리: UI는 모두 트리 구조로 위젯들이 중첩되어 구성됨
  • 비용: 상태가 바뀔 때 리빌드되는 범위가 커질수록 성능에 부담
    • 작은 위젯만 리빌드하는 게 이상적
    • setState() 위치가 중요 (최대한 하위 위젯만 리빌드하도록 설계)

7. 함수 전달 방법 3가지

형태
의미
onPressed: () {}
직접 정의한 익명 함수
onPressed: increase
이미 정의된 함수명만 전달
onPressed: () => increase()
람다식으로 wrapping 후 호출
※ 차이는 내부 동작 방식이나 클로저 캡처 여부 등 미세한 부분이지만 대부분 비슷하게 작동함.

8. setState(() {})

  • 의미: 이 함수 안의 상태 변경을 반영하고, 해당 State를 가진 위젯만 다시 그림
  • 예시:
    • setState(() { counter++; });

9. context 분리 구조 문제 요약

  1. *하위 위젯(Bottom)**이 상위 상태를 바꾸고 싶을 때 context가 필요함
  1. 그런데 상태를 가진 위젯이 중간(Middle)에 없고 상위(HomePage)에 있으면,
      • 하위에서 context를 타고 올라가서 상태 변경을 요청할 수 없음
      • 결국 상태를 상위(HomePage)에 올리면 setState() 범위가 커져서 전체 리빌드 발생
→ 해결: 상태를 필요한 만큼만 가진 중간 위젯(Middle)에 위치시키고, 상태 변경 함수는 하위로 전달만 함

10. const의 실제 효과 요약

생성 시점
효과
최초
위젯 생성 비용 발생
두 번째 이후
이전 위젯을 그대로 재사용 (캐싱)
즉, 디자인이 고정된 컴포넌트는 가능하면 const로 만들면 성능상 유리함.
Share article

harimmon