【问题标题】:didUpdateWidget called immediately after initState in Flutter在 Flutter 中的 initState 之后立即调用 didUpdateWidget
【发布时间】:2020-03-07 22:20:53
【问题描述】:

Flutter Documentation

每当小部件配置更改时调用didUpdateWidget

但是,在下面的代码中,didUpdateWidget 第一次在initState 之后被立即调用。

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Test(),
    );
  }
}

class Test extends StatefulWidget {
  @override
  _TestState createState() => _TestState();
}

class _TestState extends State<Test> {

  @override
  void initState() {
    print("initState called");
    super.initState();
  }

  @override
  void didUpdateWidget(Test oldWidget) {
    print("didUpdateWidget called");
    super.didUpdateWidget(oldWidget);
  }

  @override
  Widget build(BuildContext context) {
    return Container();
  }
}


// output
//
// initState called
// didUpdateWidget called

有人能描述一下为什么会这样吗?以及如何将整个oldWidgetwidget 进行比较

谢谢

更新
正如@pskink 提到的,didUpdateWidget 不会在initState 之后立即调用,而是在第一次构建之后调用

还有一个问题是为什么在第一次构建之后调用它,代码如下:

    print("didUpdateWidget called");   <--
    super.didUpdateWidget(oldWidget);  <--

但如果我在super.didUpdateWidget(oldWidget); 之后调用 print,它可以正常工作。

【问题讨论】:

  • 嗨。请将代码复制并粘贴到颤振项目中,您会看到它的调用。
  • 是的,你是对的,但是为什么在第一次构建之后会调用didUpdateWidget?小部件没有变化!
  • 是的,我已经知道了,但是在这个简单的示例中,没有父小部件,而是调用了 didUpdateWidget
  • 您将print 行与super.didUpdateWidget 交换,它按预期工作。所以这意味着super.didUpdateWidget 之前的任何东西都将在第一次构建后立即运行。感谢您的宝贵时间和回复
  • 只需在 dartpad.dartlang.org 的代码中首先调用 print ,您就会看到 didUpdateWidget 方法在第一次构建之后被调用

标签: flutter statefulwidget


【解决方案1】:

在我使用 Flutter 2.10.1 稳定版的测试中,didUpdateWidget 是在调用 setState() 更新 Widget 上显示的数据后才调用的。此行为与docs 中提到的描述相匹配,其中只要小部件配置更改,就会调用 didUpdateWidget 方法。调用 didUpdateWidget 方法后,会调用build

调用setState() 一次后,流程如下所示。

  1. initState()
  2. 构建()
  3. setState() 调用
  4. didUpdateWidget()
  5. 构建()

这可以在这个简单的 Flutter 应用上复制。

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

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


  @override
  void didUpdateWidget(MyHomePage oldWidget) {
    debugPrint('State didUpdateWidget');
    super.didUpdateWidget(oldWidget);
  }

  @override
  Widget build(BuildContext context) {
    debugPrint('State Widget build');
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }
}

【讨论】:

    猜你喜欢
    • 2021-07-08
    • 2016-10-24
    • 1970-01-01
    • 1970-01-01
    • 2019-11-20
    • 1970-01-01
    • 1970-01-01
    • 2019-08-30
    • 1970-01-01
    相关资源
    最近更新 更多