How do I get a child widget to update when a parent's state changes?

391

Use provider package your problem will solved easily

Share:
391
majestiq
Author by

majestiq

Updated on December 31, 2022

Comments

  • majestiq
    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
      Yeasin Sheikh almost 3 years
      im testing this , and it's working without ValueNotifier. on parent widget if value changes inside setState() it will also call it;s children to build. like here, dropDown value is updating on parent and children are depend on idFromDropdown, 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
      majestiq almost 3 years
      The 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
      Yeasin Sheikh almost 3 years
      are you using futureBuilder on childWidget?
    • majestiq
      majestiq almost 3 years
      Yes. 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
      Yeasin Sheikh almost 3 years
      let it be handle by statemanagement
    • majestiq
      majestiq almost 3 years
      what 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
    majestiq almost 3 years
    How would I know that the provider value has changed? Does provider allow me to set any callbacks on the value changing?
  • Yeasin Sheikh
    Yeasin Sheikh almost 3 years
    i prefer using riverpod here
  • hasanm08
    hasanm08 over 2 years
    Use selectors in ui and notify changes to that with notifylisteners() method in your change notifier class you should read all of provider's document