Flutter StateManagement with Provider
Hello friends,
Here we have big news from flutter team in IO19
Flutter now announced their support for web. for more details you can https://flutter.dev/web
Alongside the flutter web, they also announced a new plugin for StateManagement Here how to use it in your application
So Let’s get started
Before looking into providers lets see whatsis ChangeNotifier
this plugin uses ChangeNotifier
to to listen and update any changes.
What is ChangeNotifier
Form docs
A class that can be extended or mixed in that provides a change notification API using [VoidCallback] for notifications.
[ChangeNotifier] is optimized for small numbers (one or two) of listeners. It is O(N) for adding and removing listeners and O(N²) for dispatching notifications (where N is the number of listeners)
Provider
Existing providers
provider
exposes a few different kinds of "provider" for different types of objects.
Let's get started with our code
first things first let add plugin to pubspec.yaml
provider: ^2.0.1
http: ^0.12.0+2
Let's Write our provider class first we name it AppState
Our AppState
is extended with ChangeNotifier
which is used to notify its listeners when we call notifyListeners()
In the code, we declared two methods setDisplayText
and getDisplayText
which are used to read and write the value in our state
Now we move to our main.dart
In the code, we can notice we have used ChangeNotifierProvider
which is provided from out provider
plugin
It accepts two parameters one is builder
and the other is child
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: ChangeNotifierProvider<AppState>(
builder: (_) => AppState(),
child: MyHomePage(),
));
}
Inside the MyHomePage
we have a Scaffold
with Column
which has two Widgets TextDisplay()
and TextEditWidget()
TextDisplay(),
TextEditWidget(),
Here is our TextDisplay()
in text_display.dart
In the above code we see
Widget build(BuildContext context) {
final appState = Provider.of<AppState>(context);
return Container(
padding: const EdgeInsets.all(16.0),
child: Text(
appState.getDisplayText,
style: TextStyle(
fontSize: 24.0,
),
),
);
}final appState = Provider.of<AppState>(context);
This above line of code will get the provider that listens to any changes optionally we can also get a provider without a listener by providing listen: false
final appState = Provider.of<AppState>(context, listen: false);
Now in order to access text, we have a function in our provider called getDisplayText
appState.getDisplayText()
Here is out TextEditWidget()
in text_edit.dart
In the above code, we get our appState inside the build
function
final appState = Provider.of<AppState>(context);
In order to manipulate the text in the state we call setDisplayText(text)
function
TextField(
controller: _textEditingController,
decoration: InputDecoration(
labelText: "Some Text",
border: OutlineInputBorder(),
),
onChanged: (changed) => appState.setDisplayText(changed),
onSubmitted: (submitted) => appState.setDisplayText(submitted),
)
we are updating the state whenever out text is changes
onChanged: (changed) => appState.setDisplayText(changed)
Now we perform network operation
Now inside our app state, we have some additional functions and variables
String _dataUrl = "https://reqres.in/api/users?per_page=20";
String _jsonResonse = "";
bool _isFetching = false;
bool get isFetching => _isFetching;
Future<void> fetchData() async {
_isFetching = true;
notifyListeners();
var response = await http.get(_dataUrl);
if (response.statusCode == 200) {
_jsonResonse = response.body;
}
_isFetching = false;
notifyListeners();
}
String get getResponseText => _jsonResonse;
List<dynamic> getResponseJson() {
if (_jsonResonse.isNotEmpty) {
Map<String, dynamic> json = jsonDecode(_jsonResonse);
return json['data'];
}
return null;
}
Here we have a few more functions fetchData
, getResponseText
and getResponseJson
fetchData
will perform the network operation and update the variable with the response data (you can parse your JSON to custom model here and save it in a List
)
getResponseText
will return the plain text response
getResponseJson
will convert the response text to a Map
and returndata
field inside it which is a list of Map
To see the final app_state.dart
visit below link
Now inside out MyHomePage
widget we add two more widgets to our column
RaisedButton(
onPressed: () => appState.fetchData(),
child: Text("Fetch Data from Network"),
),
ResponseDisplay(),
So I am calling appState.fetchData()
whenever I press the button now fetchData
will take care of all the updating of the state
Here is our ResponseDisplay
Widget named response_display.dart
Here in the above code we parse the JSON and build a list of data