[Flutter] 상태관리 2

솜사탕·2024년 6월 25일

flutter

목록 보기
2/15
post-thumbnail

Valuenotifier

  • 단일값을 전달하는 Changenotifier 해당 값이 변경되면 리스너에게 알림
  • 앱의 상태 관리로 적당하지만 모든 경우에서 사용하기에 적절하지 않음
  • 개인적인 생각이지만 Stateless에서만 사용하기

setState() 없이 상태값을 변경

영향을 미치는 범위는 ValueListenableBuilder() 내에서만 허용
전체 위젯에 값을 적용하기 위해서는 setState()를 사용해야하는데 build가 완료되기 전에 setState()를 호출하게 된다면 오류가 발생

ValueListenableBuilder(
	valueListenable: _controller,
    builder: (context, value, child) {
    	return Text('$value'); // 값이 변경됨
    },
),
Text('other text : ${_controller.value}'), // 값이 변경하지 않음

Changenotifier

  • 클래스를 구독하고 해당 클래스에 변경 사항이 있을때 notifyListeners() 메서드를 호출해 해당 클래스를 구독하고 있는 위젯을 rebuild 함
  • Provider와 주로 사용된다

Provider.of(context) // 상태 구독
notifyListeners() // 상태 변경

Statenotifier

  • Immutable 상태를 관리하는 데 유용함
  • 상태를 변경을 추적하고 알리기 위함
  • Riverpo와 주로 사용된다
  • 상태 관리 로직을 분리하고, 상태의 불변성을 보장하여 코드의 가독성과 유지 보수성을 높힘
  • 명시적인 상태 변경을 통해 상태 변경의 추적이 용이함
  1. StateNotifier 정의하기
    class CounterState {
    	final int count;
    	CounterState(this.count);
    }
  2. StateNotifierProvider 정의하기
    final counterProvider = StateNotifierProvider<CounterNotifier, CounterState>((ref) {
    	return CounterNotifier();
    });
    
  3. UI에서 사용하기
    import 'package:flutter/material.dart';
    import 'package:flutter_riverpod/flutter_riverpod.dart';
    void main() {
    	  runApp(
    	    ProviderScope(
    	     child: MyApp(),
    	   ),
    	  );
    }
    class MyApp extends StatelessWidget {
    
    Widget build(BuildContext context) {
      return MaterialApp(
        home: Scaffold(
          appBar: AppBar(title: Text('StateNotifier Example')),
          body: Center(
            child: CounterText(),
          ),
          floatingActionButton: CounterButton(),
        ),
      );
    }
    }
    class CounterText extends ConsumerWidget {
    
    Widget build(BuildContext context, ScopedReader watch) {
      final counterState = watch(counterProvider);
      return Text(
        '${counterState.count}',
        style: Theme.of(context).textTheme.headline4,
      );
    }
    }
    class CounterButton extends ConsumerWidget {
    
    Widget build(BuildContext context, ScopedReader watch) {
      final counterNotifier = watch(counterProvider.notifier);
      return FloatingActionButton(
        onPressed: () {
          counterNotifier.increment();
        },
        tooltip: 'Increment',
        child: Icon(Icons.add),
      );
    }
    }

0개의 댓글