Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter redux: StoreConnector vs StoreProvider

I've been using flutter_redux for only very few days and I'm wondering what's the difference between:

class BtnCustom extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final store = StoreProvider.of<AppState>(context);

    return FlatButton(
      onPressed: store.dispatch(MyCustomAction),
      child: Text(store.state.MyCustomTxt),
    );
  }
}

and

class BtnCustom extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return StoreConnector<AppState, _ViewModel>(
      converter: (store) => _ViewModel(
          txt: store.state.MyCustomTxt,
          onPressed: store.dispatch(MyCustomAction)),
      builder: (BuildContext context, _ViewModel vm) {
        return FlatButton(
          onPressed: vm.onPressed,
          child: Text(vm.txt),
        );
      },
    );
  }
}

class _ViewModel {
  final String txt;
  final void Function() onPressed;

  _ViewModel({this.txt, this.onPressed});
}

?

The first one seems so handy to use. Are they any advantages or drawbacks of using one over another I should be aware of?

According to the documentation, the StoreConnector will rebuild the widget in it so:

  • Is it ok to not use a StoreConnector when you don't need to rebuild a widget?
  • Is it ok to have multiple widgets within a StoreConnector?
like image 824
Olivier Picault Avatar asked Mar 03 '23 16:03

Olivier Picault


1 Answers

StoreConnector gives you more control over widget, especially when you don't want to rebuild it. StoreConnector:

  • lets you detect whether the ViewModel has changed (whether widget should be rebuilt) if you use distinct: true and override hashCode and == in your ViewModel;

  • lets you skip widget rebuild altogether by quickly checking some specific store.state:

     StoreConnector<AppState, MyViewModel>(
         distinct: true,
         ignoreChange: (state) {      
             return state.someVariable == theValueIDontCareAbout;
         },
         ...
     ),
    
     class MyViewModel{
         @override
         bool operator ==(other) {
              return (other is MyViewModel) && (this.someVmVariable == other.someVmVariable);
         }
    
         @override
         int get hashCode {
             int result = 17;
             result = 37 * result + someVmVariable.hashCode;
             return result;
         }
     }
    

And some more fine-grained controls. Take a look at the documentation of StoreConnector's constructor. If multiple widgets inside store sonnector share the same ViewModel it is natural to have them like that. However, if it's possible to prevent them from rebulding by separating their ViewModels you can use separate StoreConnectors.

like image 166
Alex Kuzmin Avatar answered Mar 10 '23 23:03

Alex Kuzmin