didChangeDependencies 和 initState 有什么区别?

moh*_*mad 41 dart flutter

我是 flutter 的新手,当我想在 InitState 中调用我的上下文时,它会抛出一个错误:这是关于 BuildContext.inheritFromWidgetOfExactType 但后来我使用了 didChangeDependencies 并且它可以正常工作。

现在我有两个问题:

1- 为什么在 initState 中调用我们的上下文不起作用,但在从 didChangeDependencies 调用时却起作用?(因为正如我在官方文档中读到的那样This method is also called immediately after [initState],它们都将在构建方法之前被调用。)

2- 为什么我们可以在 build 方法之外访问我们的上下文(因为在那里我们build(BuildContext context)可以使用我们的上下文,但是在 didChangeDependencies 中我们没有类似的东西didChangeDependencies(BuildContext context),所以我们可以从哪里调用上下文来使用它)?

San*_*ngh 47

从状态加载其依赖项的那一刻起,我们就可以使用状态的上下文。

在调用 build 时,上下文对我们可用并作为参数传递。

现在继续,在状态加载其依赖项之前调用 initstate,因此没有可用的上下文,如果您在 initstate 中使用上下文,则会出现错误。但是 didChangeDependencies 在状态加载其依赖项后不久被调用,此时上下文可用,因此您可以在此处使用上下文。

但是,在调用 build 之前调用它们。唯一的区别是,一个在状态加载其依赖项之前调用,另一个在状态加载其依赖项后片刻调用。

  • @abrsh 嘿,看,当我们第一次初始化数据时,initstate 仅被调用一次。我们不能一次又一次地调用 initstate 来更新数据,因为没有上下文,所以它不知道要更新哪些数据(即再次初始化)。因此,为了解决这个问题,我们改变了依赖关系,它具有上下文并知道要更新哪些数据。所以是的,我们可以一次又一次地调用 didchangedependency 来更新/初始化我们的数据 (9认同)
  • 快速问题 @SanjaySingh initState 仅被调用一次,那么 didChangeDependency 呢?因为我在使用的时候发现自己陷入了一个不断的循环!预先感谢您的回答! (3认同)

fed*_*lov 23

我发现initState和 之间存在显着差异didChangeDependencies

  • initState只被调用一次对于小部件
  • didChangeDependencies每个小部件生命周期可能会被多次调用(在我的例子中,当键盘出现/消失时被调用)


jit*_*555 15

initState()当新的 Widget 插入到树中时调用。框架将为它创建的每个 [State] 对象调用此方法一次。这将被调用一次,以便执行只需要执行一次的工作,但请记住context不能在此处使用,因为小部件状态被加载,仅initState()完成工作。

句法:

@override
  void initState() {
    debugPrint('initState()');
    super.initState();
  }
Run Code Online (Sandbox Code Playgroud)

didChangeDependencies()当此 [State] 对象的依赖项发生更改时调用。

那么,它到底是如何被调用的呢?根据上面的定义,看起来它会在状态改变后被调用,但是我们如何知道状态改变了呢?

例子:

下面的示例使用Provider状态管理机制从父窗口小部件更新子窗口小部件。有Provider一个名为 的属性updateShouldNotify,决定状态是否更改。如果它返回true,则只会didChangeDependencies在课堂上被调用ChildWidget

updateShouldNotify 在内部默认返回 true,因为它知道状态已更改。那么为什么我们需要 updateShouldNotify 呢?这是需要的,因为如果有人想要在特定条件下更新状态,例如:如果 UI 需要仅显示even值,那么我们可以添加一个条件,例如

updateShouldNotify: (oldValue, newValue) => newValue % 2 == 0,
Run Code Online (Sandbox Code Playgroud)

代码片段:

class ParentWidget extends StatefulWidget {
  ParentWidget({Key key, this.title}) : super(key: key);

  final String title;

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

class _ParentWidgetState extends State<ParentWidget> {
  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: <Widget>[
              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<ChildWidget> {
  int _counter = 0;

  @override
  void initState() {
    print('initState(), counter = $_counter');
    super.initState();
  }

  @override
  void didChangeDependencies() {
    _counter = Provider.of<int>(context);
    print('didChangeDependencies(), counter = $_counter');
    super.didChangeDependencies();
  }

  @override
  Widget build(BuildContext context) {
    print('build(), counter = $_counter');
    return Text(
      '$_counter',
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

输出日志:

I/flutter ( 3779): didChangeDependencies(), counter = 1
I/flutter ( 3779): build(), counter = 1
Run Code Online (Sandbox Code Playgroud)

详细解释:

https://medium.com/@jitsm555/ Differentiate- Between-didchangedependency-and-initstate-f98a8ae43164?sk=47b8dda310f307865d8d3873966a9f4f


zex*_*oor 5

initState()是创建小部件后调用的第一个方法。onCreate()这与Android 或viewDidLoad()iOS 中类似 。

框架第一次构建小部件时,它会调用didChangeDependencies() after initState()didChangeDependencies()如果您的状态对象依赖于已更改的继承小部件,它可能会再次调用。

在此输入图像描述

来源:kodeco 发布的 Flutter Apprentice