状態管理の要点はその状態に影響を受けるWidgetのみが状態変化に対する処理を行えるように効率化することです。
InheritedWidget
Flutter自身を構成するWidgetの一つ。Widgetツリーの配下に効率的に情報を伝える仕組みを提供します。
import 'package:flutter/material.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: MyHomePage( key: null, child: Scaffold( appBar: AppBar( title: Text("Inherited Widget Sample"), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ WidgetNumText(), WidgetCenterText( key: null, ), ], ), ), floatingActionButton: WidgetIncrementBtn(), ), ), ); } } class MyHomePage extends StatefulWidget { MyHomePage({required Key? key, required this.child}) : super(key: key); final Widget child; @override _MyHomePageState createState() => _MyHomePageState(); static _MyHomePageState of(BuildContext context, {bool rebuild = true}) { return rebuild ? (context.dependOnInheritedWidgetOfExactType<_InheritedWidget>() as _InheritedWidget) .data : (context .getElementForInheritedWidgetOfExactType<_InheritedWidget>()! .widget as _InheritedWidget) .data; } } class _MyHomePageState extends State<MyHomePage> { int _counter = 0; void _incrementCounter() { setState(() { _counter++; }); } @override Widget build(BuildContext context) { return _InheritedWidget( child: widget.child, data: this, ); } } class WidgetIncrementButton extends StatelessWidget { @override Widget build(BuildContext context) { final _MyHomePageState state = MyHomePage.of(context, rebuild: false); return FloatingActionButton( onPressed: () => state._incrementCounter(), tooltip: 'Increment', child: Icon(Icons.add), ); } } class _InheritedWidget extends InheritedWidget { _InheritedWidget({ Key? key, required Widget child, required this.data, }) : super(key: key, child: child); final _MyHomePageState data; @override bool updateShouldNotify(InheritedWidget oldWidget) => true; } class WidgetNumText extends StatelessWidget { @override Widget build(BuildContext context) { final _MyHomePageState state = MyHomePage.of(context); return Text( '${state._counter}', style: Theme.of(context).textTheme.headline4, ); } } class WidgetIncrementBtn extends StatelessWidget { @override Widget build(BuildContext context) { final _MyHomePageState state = MyHomePage.of(context, rebuild: false); return FloatingActionButton( onPressed: () => state._incrementCounter(), tooltip: 'Increment', child: Icon(Icons.add), ); } } class WidgetCenterText extends StatelessWidget { const WidgetCenterText({required Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Text('You have pushed the button this many times:'); } }
Memo
Shader compilation errorが出たら
エミュレーターからアプリを消してflutter cleanする
Provider
InheritedWidgetのラッパークラスで状態管理とDI機能を提供します。
StateNotifer
状態管理パッケージでProviderをベースに作られている。同じ作者。