Navigate to a new screen and passing the redux store state when using a viewmodel
For the most common use case of an app wide state you can just use the StoreConnector
in any screen where you need the state. You are already using it in your Menu class, but you can use it similarly in your MySettingsScreen
build method override.
Additionally your view models are being created using the store, so the idea is that you include all information that is required from the store to build the view when you build the view model. For example:
class MyViewModel {
String myInfo;
factory MyViewModel.create(Store<AppState> store) {
return MyViewModel(myInfo: store.state.myInfoState);
}
...
}
Then you use that information from your viewmodel:
@override
Widget build(BuildContext context) => StoreConnector<AppState, MyViewModel>(
converter: (Store<AppState> store) => MyViewModel.create(store),
builder: (BuildContext context, MyViewModel viewModel) {
return Text(viewModel.myInfo);
}
You could use the same mechanism to keep a reference to the store in the viewModel:
class MyViewModel {
Store<AppState> myStore;
factory MyViewModel.create(Store<AppState> store) {
return MyViewModel(myStore: store);
}
...
}
This allows you to use it in your build method directly:
@override
Widget build(BuildContext context) => StoreConnector<AppState, MyViewModel>(
converter: (Store<AppState> store) => MyViewModel.create(store),
builder: (BuildContext context, MyViewModel viewModel) {
return Text(viewModel.myStore.state.myInfo);
}
Note that the first pattern may be preferable if you want to keep a logical separation between the view model and the redux persistence.
Comments
-
Giacomo M over 1 year
I have the need to pass the redux store state from a screen to another inside the
build
function.
My problem is that in thebuild
function I have the ViewModel variable, that does not have a reference to the state.This is the code of the screen:
import ... class Menu extends StatefulWidget { @override _MenuState createState() => _MenuState(); } class _MenuState extends State<Menu> { @override Widget build(BuildContext context) { return StoreConnector<AppState, ViewModelLogin>( converter: (store) => ViewModelLogin.create(store), builder: (context, ViewModelLogin viewModel) { Widget _buildPage(isLoggedIn) { if (isLoggedIn) { return ListView( children: <Widget>[ ListTile( title: Text('Settings'), onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => MySettingsScreen(), // <-- HERE I NEED TO PASS THE STATE TO MySettingsScreen ), ); }, ), ListTile( leading: Image.network( viewModel.loginType == 'facebook' ? 'https://img.icons8.com/color/52/000000/facebook.png' : 'https://image.flaticon.com/teams/slug/google.jpg' , width: 30.0, ), title: Text('Exit'), onTap: () { viewModel.onLogout(viewModel.loginType); } ), ], ); } else { return LoginScreen(appBar: false); } } return _buildPage(viewModel.isLoggedIn); }, ); } }
The reason I need to pass the state to MySettingsScreen is that in the screen I need a store variable to do a get call to a webservice (outside the build function).
This is a part of MySettingsScreen where I need the store state:
import ... class MySettingsScreen extends StatefulWidget { final AppState state; MySettingsScreen({Key key, @required this.state}) : super(key: key); @override _MySettingsScreenState createState() => _MySettingsScreenState(); } class _MySettingsScreenState extends State<MySettingsScreen> { @override void initState() { super.initState(); _load(); } void _load() async { final url = 'url'; try { http.Response res = await http.get(url, headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + // <-- HERE I NEED THE STORE VARIABLE }); final data = json.decode(res.body); tmpItems = _parseItems(data["bookings"]); } catch(e) { print(e); } } @override Widget build(BuildContext context) { ... } }
-
Michael Osofsky over 4 yearsWhen the user interacts with the view I'm wondering if the ViewModel responds by dispatching actions to the reducer. What role does the ViewModel play in event handling in an Android app modeled after Redux?
-
EDPChinthana over 3 yearsIs there any way to pass store reference to a function and change the redux store from there? I am a beginner to flutter and redux. Please don't mind if this is a silly question:C