본문 바로가기

Flutter/07 State - Provider

[Flutter] Provider Access - Named route

오늘은 Provider 적용후 네임드 라우팅(Named route)을 통한 화면 전환시 데이터 공유에 대해서 정리했습니다.

개발환경 : 윈도우11, 안드로이드 스튜디오(Arctic Fox 2020.3.1 Patch 4), flutter 2.10

소스코드 - Release 20_Provider_Access_named_route · mike-bskim/provider_overview (github.com)

 

Release 20_Provider_Access_named_route · mike-bskim/provider_overview

 

github.com

 

기본 구조는 이전 블로그와 동일하지만, 몇가지 수정사항이 있다.

1. Named route 를 사용하면 라우팅별로 모두 Provider 로 wrapping 해야 한다.

2. 각 각의 wrapping 별 value 에 전달할 공용 인스턴스를 미리 생성해야 한다.

3. ChangeNotifierProvider 를 통해서 생성한 인스턴스가 아니므로 dispose 해줘야 한다.

4. dispose 하기 위해서 위젯을 StatefulWidget 으로 변경해야 한다.

내용이 약간 거창하지만 소스코드를 보면 이해하기 좀 쉬워진다.

 

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  State<MyApp> createState() => _MyAppState();
}
// 4. dispose 하기 위해서 위젯을 StatefulWidget 으로 변경
class _MyAppState extends State<MyApp> {
// 2. provider 에 전달할 공용 인스턴스 생성
  final Counter _counter = Counter();

  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
    // 3. ChangeNotifierProvider 를 통해서 create 하지 않아서 
    // 수동으로 삭제해야 함.
    _counter.dispose();
  }

  @override
  Widget build(BuildContext context) {
    debugPrint('MyApp >> build');

    return MaterialApp(
      title: 'Named Route',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      // 이해를 돕기 위해서 지우지 않고 주석처리함.
      // home: ChangeNotifierProvider<Counter>(
      //   create: (context) => Counter(),
      //   child: const MyHomePage(),
      // ),
      routes: {
      // 1. ChangeNotifierProvider.value 로 wrapping
        '/': (context) => ChangeNotifierProvider.value(
              value: _counter,
              child: const MyHomePage(),
            ),
      // 1. ChangeNotifierProvider.value 로 wrapping
        '/counter': (context) => ChangeNotifierProvider.value(
              value: _counter,
              child: const ShowMeCounter(),
            ),
      },
    );
  }
}

class MyHomePage extends StatelessWidget {
  const MyHomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(
              child: const Text(
                'Show Me Counter',
                style: TextStyle(fontSize: 20.0),
              ),
              onPressed: () {
                Navigator.pushNamed(context, '/counter');
              },
            ),
            const SizedBox(height: 20.0),
            ElevatedButton(
              child: const Text(
                'Increment Counter',
                style: TextStyle(fontSize: 20.0),
              ),
              onPressed: () {
                context.read<Counter>().increment();
              },
            )
          ],
        ),
      ),
    );
  }
}

 

참고로 ChangeNotifierProvider 를 통해서 create 하면 자동으로 dispose 되므로 편리하다.

 

 

 

 

[참고자료] udemy - Flutter Provider Essential 코스 (Korean)