Flutter状态管理:使用Provider和Redux管理应用状态

狂野之心 2022-07-14 ⋅ 14 阅读

在开发Flutter应用时,状态管理是一项非常重要的任务。由于Flutter的UI是根据状态来变化的,良好的状态管理可以使应用更加可维护和扩展。在Flutter中,我们可以使用ProviderRedux来管理应用的状态。

Provider

Provider是一个简单直观的状态管理库,它允许我们将应用的状态共享给整个应用。它通过提供InheritedWidgetChangeNotifier来实现状态管理。

InheritedWidget

InheritedWidget是Flutter的一个基本类,它可以将状态向下传递给子组件。在Provider中,我们可以将应用的状态放在一个继承自InheritedWidget的类中,并在整个应用中共享。

class MyAppState extends InheritedWidget {
  final MyState state;

  const MyAppState({
    Key? key,
    required Widget child,
    required this.state,
  }) : super(key: key, child: child);

  static MyAppState? of(BuildContext context) {
    return context.dependOnInheritedWidgetOfExactType<MyAppState>();
  }

  @override
  bool updateShouldNotify(MyAppState old) => old.state != state;
}

通过MyAppState,我们可以将state作为应用的状态进行共享。

ChangeNotifier

ChangeNotifier是Provider提供的另一个基本类,它可以监听状态的变化并通知相应的监听者进行更新。在Provider中,我们可以通过继承ChangeNotifier来实现具有状态变化通知能力的类,然后将其包装在MyAppState中。

class MyState extends ChangeNotifier {
  int counter = 0;

  void incrementCounter() {
    counter++;
    notifyListeners();
  }
}

MyState中,我们定义了一个名为counter的状态,然后在incrementCounter()方法中修改状态并通知监听者进行更新。

使用Provider

在使用Provider时,我们需要将根组件包装在MyAppState中,并使用Provider.ofConsumer来获取和监听状态。

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (context) => MyState(),
      child: MaterialApp(
        title: 'Flutter Provider Demo',
        home: MyHomePage(),
      ),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var state = Provider.of<MyState>(context);
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Provider Demo'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'Counter: ${state.counter}',
              style: TextStyle(fontSize: 24),
            ),
            ElevatedButton(
              onPressed: () {
                state.incrementCounter();
              },
              child: Text('Increment'),
            ),
          ],
        ),
      ),
    );
  }
}

在上述代码中,我们使用ChangeNotifierProvider包装了MyState,并将其提供给整个应用。然后,在MyHomePage中通过Provider.of<MyState>(context)获取状态,并在UI中使用它。

Redux

Redux是一种更为强大和灵活的状态管理模式,它通过单一的状态树和不可变的状态来管理应用的状态。在Flutter中,我们可以使用flutter_redux库来实现Redux的状态管理。

定义状态

在使用Redux时,我们首先需要定义应用的状态。我们可以使用类来定义状态,并将所有的状态打包在一个单一的类中。

class AppState {
  final int counter;

  AppState(this.counter);

  AppState.initialState() : counter = 0;
}

在上述代码中,我们定义了一个名为AppState的类,并在其中定义了一个名为counter的状态。我们还提供了一个名为initialState()的工厂方法来创建初始状态。

定义操作

在Redux中,我们通过操作来改变状态。我们可以使用类来定义操作,并在操作中指定需要改变的状态。

class IncrementCounterAction {}

AppState counterReducer(AppState state, dynamic action) {
  if (action is IncrementCounterAction) {
    return AppState(state.counter + 1);
  }

  return state;
}

在上述代码中,我们定义了一个名为IncrementCounterAction的操作。然后,在counterReducer中根据不同的操作来改变状态。

创建Store

在Redux中,我们需要使用Store来保存应用的状态。我们可以通过使用reduxflutter_redux库来创建和使用Store。

void main() {
  final store = Store<AppState>(
    counterReducer,
    initialState: AppState.initialState(),
  );

  runApp(MyApp(store));
}

class MyApp extends StatelessWidget {
  final Store<AppState> store;

  MyApp(this.store);

  @override
  Widget build(BuildContext context) {
    return StoreProvider(
      store: store,
      child: MaterialApp(
        title: 'Flutter Redux Demo',
        home: MyHomePage(),
      ),
    );
  }
}

在上述代码中,我们创建了一个名为store的Store,并将其提供给整个应用。然后,在MyHomePage中通过StoreProvider获取Store并使用它。

使用StoreConnector

在使用Redux时,我们可以使用StoreConnector来连接Store和UI组件,并在UI组件中获取和改变状态。

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return StoreConnector<AppState, ViewModel>(
      converter: (store) => ViewModel(
        counter: store.state.counter,
        incrementCounter: () => store.dispatch(IncrementCounterAction()),
      ),
      builder: (context, vm) {
        return Scaffold(
          appBar: AppBar(
            title: Text('Flutter Redux Demo'),
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Text(
                  'Counter: ${vm.counter}',
                  style: TextStyle(fontSize: 24),
                ),
                ElevatedButton(
                  onPressed: vm.incrementCounter,
                  child: Text('Increment'),
                ),
              ],
            ),
          ),
        );
      },
    );
  }
}

class ViewModel {
  final int counter;
  final Function() incrementCounter;

  ViewModel({required this.counter, required this.incrementCounter});
}

在上述代码中,我们使用StoreConnector将Store和UI组件连接起来,并通过converter获取和改变状态。然后,在builder中构建UI组件,并使用状态来更新UI。

总结

在Flutter中,状态管理是一项非常重要的任务。通过使用Provider和Redux,我们可以轻松地管理应用的状态。Provider提供了简单直观的状态共享能力,而Redux提供了更为强大和灵活的状态管理模式。根据应用的需求,我们可以选择适合的状态管理方式来提高应用的可维护性和扩展性。


全部评论: 0

    我有话说: