상태관리란?
애플리케이션의 상태(state)를 관리하는 것을 의미합니다.
상태는 사용자 인터페이스(UI)와 상호작용하거나 애플리케이션의 내부 동작을 관리하는 데 필요한 데이터를 나타냅니다.
상태 관리는 애플리케이션이 예측 가능한 방식으로 동작하도록 도와주며, 특히 복잡한 애플리케이션에서는 필수적인 요소입니다.
상태 관리의 필요성
- UI 업데이트
- 상태가 변경될 때 UI를 자동으로 업데이트해야 합니다.
예를 들어, 사용자가 버튼을 클릭하면 버튼의 상태나 관련된 UI 요소가 변경될 수 있습니다.
- 상태가 변경될 때 UI를 자동으로 업데이트해야 합니다.
- 일관성 유지
- 여러 UI 요소가 동일한 상태를 공유하는 경우 상태 변경이 일관성 있게 반영되어야 합니다.
- 유지보수
- 상태를 중앙에서 관리하면 코드의 유지보수와 확장이 쉬워집니다.
상태 관리의 종류
- setState
- Flutter의 내장 상태 관리 방법으로 간단한 상태 변경을 처리할 때 사용.
- InheritedWidget
- 데이터 및 상태를 트리 구조의 하위 위젯에 전달하는 데 사용.
- Provider
- InheritedWidget을 더 쉽게 사용할 수 있게 해주는 패키지.
- 의존성 주입과 상태 관리를 간편하게 함.
- flutter 공식 라이브러리.
- Riverpod
- Provider의 단점을 보완한 패키지.
- 더 안전하고 유연한 상태 관리를 제공.
- flutter에 의존하지 않음.
- 컴파일 동안 안전함.
- BLoC (Business Logic Component)
- 비즈니스 로직을 분리하여 재사용 가능하게 만드는 패턴.
- 스트림을 통해 상태를 관리함.
- Redux
- 애플리케이션의 상태를 중앙에서 관리.
- 상태 변경을 예측 가능한 방식으로 처리하는 패턴.
요즘은 Provider보단 안전성과 여러 가지 장점 때문에 Riverpod을 많이 사용하는 것 같습니다.
하지만 지금은 이중에서 플러터 공식 라이브러리인 Provider에 대해서 알아보겠습니다.
Provider란?
Provider 패키지는 플러터에서 사용되는 상태 관리 프레임워크 중 하나입니다.
하지만 많은 Provider를 사용할 경우, 각각의 Provider를 개별적으로 선언하면 코드가 복잡해질 수 있습니다.
이를 해결하기 위해 MultiProvider를 사용하면 여러 Provider를 한 번에 선언하고 관리할 수 있습니다.
Provider의 주요 개념
- 의존성 주입
- Provider는 객체를 생성하고 그 객체를 트리 구조의 하위 위젯에 주입합니다.
- 이를 통해 위젯 트리 전체에서 객체를 사용할 수 있습니다.
- 상태 관리
- Provider는 상태 변화를 감지하고, 상태가 변경될 때 이를 구독하고 있는 위젯들에게 알림을 보냅니다.
- 이를 통해 UI를 자동으로 업데이트할 수 있습니다.
왜 상태 관리 라이브러리를 사용하는가?
플러터 앱은 위젯 트리 구조로 구성되어 있습니다.
위젯 트리에서 각 위젯은 자체적인 상태를 가지고 있으며, 이 상태는 위젯의 UI를 결정하는 데 사용됩니다.
하지만 앱이 복잡해지면서 여러 위젯에서 동일한 상태를 공유해야 하는 경우가 발생하게 됩니다.
이 경우 단순히 setState()를 사용하여 상태를 변경하면 위젯 트리가 불필요하게 다시 빌드되고 코드가 복잡해지고 유지보수하기 어려워질 수 있습니다.
그렇기에 상태 관리 도구를 사용하면 앱의 전체적인 상태를 중앙 집중적으로 관리하고, 여러 위젯에서 쉽게 공유할 수 있습니다.
또한, 상태 변경에 따라 위젯 트리가 다시 빌드되는 것을 최적화하여 앱의 성능을 향상할 수 있습니다.
쉽게 말하면 상태관리 라이브러리를 구독한 위젯만 새로고침이 됩니다.
사용법
flutter pub add provider
위 구문을 복사하여
사용하고자 하는 프로젝트의 터미널에서 붙여넣어 줍니다.
사용하고자 하는 클래스에
extends나 with 를 사용하여 ChangeNotifier {} 를 상속하여 줍니다.
그리고 상태를 변경할 때 주는 notifyListeners()를 메서드 끝줄에 넣어 변경사항을 알리도록 합니다.
with와 extends의 차이점은
를 참고하시면 됩니다.
runApp에서 MyApp()을 지워주고 멀티프로바이더를 [] 리스트의 형태로 설정해 준 후
하위카테고리에 MyApp()을 선언해 줍니다.
그리고 이러한 형태로 Class를 <widget>화 시켜 사용하면
이러한 형태처럼 MultiProvider를 사용하면 하나의 루트에서 관리할 수 있습니다.
Consumer
Consumer는 특정 데이터(클래스)에 의존하는 위젯을 감싸서, 해당 데이터가 변경될 때만 그 위젯을 리빌드 합니다.
이를 통해 불필요한 리빌드를 방지하고 성능을 최적화 할 수 있습니다.
// 기본 Consumer
Consumer<MyModel>(
builder: (context, myModel, child) {
return Text(myModel.someValue);
},
);
멀티 프로바이더를 사용하고 싶을 때
Consumer2<FirstModel, SecondModel>(
builder: (context, firstModel, secondModel, child) {
return Column(
children: [
Text(firstModel.someValue),
Text(secondModel.anotherValue),
],
);
},
);
프로바이더의 일부 값만 사용할 때
Consumer<MyModel>(
builder: (context, myModel, child) {
return Text(myModel.someSpecificValue);
},
);
미리 정의된 위젯을 재사용할 때
Consumer<MyModel>(
builder: (context, myModel, child) {
return Column(
children: [
Text(myModel.someValue),
child,
],
);
},
child: RaisedButton(
onPressed: () {
// something
},
child: Text('Button'),
),
);
여기서 꺽쇠 안 <MyModel>은 속성이나 매서드를 class로 정의된 class명을 말합니다.
'Flutter > tip' 카테고리의 다른 글
[플러터 Flutter] GitHub Access Token 발급방법 / 깃허브 토큰 발급방법 (0) | 2024.09.12 |
---|---|
[플러터 Flutter] 소셜로그인 카카오톡 2 social login with Kakao 2 (0) | 2024.07.12 |
[플러터 Flutter] 객체지향(Object Oriented Programing,OOP)의 이해 (0) | 2024.07.05 |
[플러터 Flutter] 안드로이드 패키지명, iOS 번들아이디 찾기 Find Android Package Name, iOS BundleID (1) | 2024.06.16 |
[플러터 Flutter] 맥에서 안드로이드 키해시 구하기 디버그/릴리즈 Obtain Android KeyHash from Mac (0) | 2024.06.16 |