How do I get a child widget to update when a parent's state changes?
Use provider package your problem will solved easily
majestiq
Updated on December 31, 2022Comments
-
majestiq over 1 year
Apologies in advance for posting Pseudo code. Real code would be too long.
I have a screen where I have a drop down at the top where a user can select an option. The rest of the page updates based on that option. Something like this:
// state variable String idFromDropdown; Column( children: [ DropDownWidget(), ChildWidget1(myId: idFromDropDown), ChildWidget2(myId: idFromDropDown), ChildWidget3(myId: idFromDropDown), ] )
In the child widgets, I am using widget.myId to pass into a backend service and read new data.
Expectation is that when the dropdown changes and I call
setState((val)=>{idFromDropdown = val});
then the value would cascade into the three child widgets. Somehow trigger the widgets to reconnect to the backend service based on the new value of widget.myId.
How do I trigger a state update on the child widgets?
I ended up using a ValueNotifier. Instead of directly using a string and passing that into the child widgets. I ended up doing something like:
ValueNotifier<String> idFromDropdown; ... setState((val)=>{idFromDropdown.value = val});
Then in each widget, I am adding a listener onto the ValueNotifier coming in and retriggering the read to the backend service.
While this works, I feel like I'm missing something obvious. My childwidgets now take in a ValueNotifier instead of a value. I'm afraid this is going to make my ChildWidgets more difficult to use in other situations.
Is this the correct way of doing this?
-
Yeasin Sheikh almost 3 yearsim testing this , and it's working without
ValueNotifier
. on parent widget if value changes insidesetState()
it will also call it;s children to build. like here, dropDown value is updating on parent and children are depend onidFromDropdown
, if you just pass like this, childrens will rebuild here. I just tested it to answer this question, if you wish i can share it on answer. -
majestiq almost 3 yearsThe issue is that even if the state is changing, what I really need to do is trigger some kind of "loadData(myID)" function in the child to get the new data. On first create, I call this function from initState() to get the data. Now when the value of idFromDropdown changes, I don't know how to trigger the loadData(myId) with the new id. I can't find a "onStateChange" type callback in flutter.
-
Yeasin Sheikh almost 3 yearsare you using
futureBuilder
on childWidget? -
majestiq almost 3 yearsYes. Basically in the child widget, I call loadData from the initstate. That returns a future. Then in the build method, there is a future builder to create the UI. I need a way to retrigger loadData. That would allow me to create a new future which would be picked up by future builder.
-
Yeasin Sheikh almost 3 yearslet it be handle by statemanagement
-
majestiq almost 3 yearswhat I'm trying to say is that it is not getting handled by state management. When the state in the parent changes, it does change the value of myID inside the child. ie: in the child "widget.myID" has a new value. However, that is not enough. I need to trigger a function that would load the new data from the backend. How do I trigger that load? that is the question. Meaning, if I was just printing the new myID in a text field, Text(myID) it would get updated. However, I need to use myID to trigger a new backend call (create a new future).
-
-
majestiq almost 3 yearsHow would I know that the provider value has changed? Does provider allow me to set any callbacks on the value changing?
-
Yeasin Sheikh almost 3 yearsi prefer using riverpod here
-
hasanm08 over 2 yearsUse selectors in ui and notify changes to that with notifylisteners() method in your change notifier class you should read all of provider's document