What is the difference between didChangeDependencies and initState?

后端 未结 8 937
刺人心
刺人心 2021-01-31 17:09

I am new to flutter and when I want to call my context in InitState it throws an error : which is about BuildContext.inheritFromWidgetOfExactType but then I use did

8条回答
  •  情歌与酒
    2021-01-31 18:02

    initState() Called when new Widget is inserted into the tree. The framework will call this method exactly once for each [State] object it creates. This will be called once so perform work which required to be performed only once, but remember context can't be used here, as widget state gets loaded only initState() work is done.

    Syntax:

    @override
      void initState() {
        debugPrint('initState()');
        super.initState();
      }
    

    didChangeDependencies() Called when a dependency of this [State] object changes.

    So, exactly How it gets called? as by the above definition, it looks like it will be called after state changes but how we come to know the state is changed?

    Example:

    The below example uses the Provider state management mechanism to update the child widget from the parent widget. The Provider has an attribute called updateShouldNotify which decides whether to state is changed or not. If it's returning true then only didChangeDependencies gets called in ChildWidget class.

    updateShouldNotify is returning true by default internally, as it knows the state got changed. Then Why we need updateShouldNotify? it's need because if someone wants to update the state on a specific condition, Eg: if UI required to show only even values then we can add a condition like

    updateShouldNotify: (oldValue, newValue) => newValue % 2 == 0,
    

    Code Snippet:

    class ParentWidget extends StatefulWidget {
      ParentWidget({Key key, this.title}) : super(key: key);
    
      final String title;
    
      @override
      _ParentWidgetState createState() => _ParentWidgetState();
    }
    
    class _ParentWidgetState extends State {
      int _counter = 0;
    
      void _incrementCounter() {
        setState(() {
          _counter++;
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('Life Cycle'),
          ),
          body: Provider.value(
            value: _counter,
            updateShouldNotify: (oldValue, newValue) => true,
            child: Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Text(
                    'Press Fab button to increase counter:',
                  ),
                  ChildWidget()
                ],
              ),
            ),
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: _incrementCounter,
            tooltip: 'Increment',
            child: Icon(Icons.add),
          ),
        );
      }
    }
    
    class ChildWidget extends StatefulWidget {
      @override
      _ChildWidgetState createState() => _ChildWidgetState();
    }
    
    class _ChildWidgetState extends State {
      int _counter = 0;
    
      @override
      void initState() {
        print('initState(), counter = $_counter');
        super.initState();
      }
    
      @override
      void didChangeDependencies() {
        _counter = Provider.of(context);
        print('didChangeDependencies(), counter = $_counter');
        super.didChangeDependencies();
      }
    
      @override
      Widget build(BuildContext context) {
        print('build(), counter = $_counter');
        return Text(
          '$_counter',
        );
      }
    }
    

    Output Logs:

    I/flutter ( 3779): didChangeDependencies(), counter = 1
    I/flutter ( 3779): build(), counter = 1
    

    For detail explanation:

    https://medium.com/@jitsm555/differentiate-between-didchangedependencies-and-initstate-f98a8ae43164?sk=47b8dda310f307865d8d3873966a9f4f

提交回复
热议问题