Flutter - Why is child widget's initState() is not called on every rebuild of Parent widget?

社会主义新天地 提交于 2021-02-18 20:00:13

问题


I have a Parent widget, which holds some state, a counter in this case.

This state is passed on to a Child widget using its constructor.

Now, how I understand it, the Child should get re-built every-time Parent's state changes, since it's inside the build() function of Parent, and build() gets called every-time the state changes.

This concept lead me to believe that the INIT STATE! message would be printed every time the counter changes. But it is not the case!

I essentially want a "hook" that gets fired only once, whenever the Child's constructor arguments (message) change.

Can someone please explain why this is the case, and what is the right way to have the aforementioned "hook"?

class Child extends StatefulWidget {
  final String message;

  const Child(this.message, {Key key}) : super(key: key);

  @override
  _ChildState createState() => _ChildState();
}

class _ChildState extends State<Child> {
  @override
  void initState() {
    print("INIT STATE!");
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Text(widget.message),
    );
  }
}

class Parent extends StatefulWidget {
  @override
  _ParentState createState() => _ParentState();
}

class _ParentState extends State<Parent> {
  int _counter = 0;

  @override
  void initState() {
    Timer.periodic(Duration(seconds: 1), (_) {
      if (mounted) {
        setState(() {
          _counter += 1;
        });
      }
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Child(_counter.toString());
  }
}

回答1:


Ok, looks like this was clearly mentioned in the State class' docs.

The correct way to do this is to override the didUpdateWidget method in the State subclass.




回答2:


Thanks to @Dev Aggarwal.

Extending to Dev Aggarwal's answer, i have included example here.

Implement didUpdateWidget() method in Child widget. When ever parent state changed, didUpdateWidget() method will call in child widget.

Implement didUpdateWidget() method in Child widget.

@override
  void didUpdateWidget(<YourChildScreen> oldWidget) {

    super.didUpdateWidget(oldWidget);

    print("oldWidget.searchTerm is ${oldWidget.searchTerm}");
    print("widget.searchTerm is ${widget.searchTerm}");

    if (oldWidget.searchTerm != widget.searchTerm) {

      this.updateChildWithParent();

    }
  }


void updateChildWithParent() {
    print("updateChildWithParent/search screen");
    setState(() {

      _mJsonLoaded = false; // For loader
      if (listArray.length > 0) {
        listArray.clear();
      }
    });

    // Do whatever you want here…
    // Like call api call again in child widget.
  }

I hope it will useful.



来源:https://stackoverflow.com/questions/54759920/flutter-why-is-child-widgets-initstate-is-not-called-on-every-rebuild-of-pa

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!