Flutter 2 如何实现父组件修改传递给子组件的动态数据
问题根因
你当前的代码无法实现需求的核心原因是:子组件仅在初始化initState阶段将父组件传递的test参数赋值给了自身State内的test变量,而initState生命周期只会在组件首次挂载时执行一次。后续父组件传递新的test值时,子组件不会主动同步更新自身State内的变量,因此展示的文本不会变化。
实现方案
以下提供两种适配不同业务场景的实现方式:
方案1:保留子组件内部State变量(适用于子组件自身也需要修改test值的场景)
父组件文件代码
仅需要在按钮点击回调中调用setState更新自身存储的text变量,触发重绘将新值传递给子组件即可:
class Parent extends StatefulWidget { const Parent({ Key key }) : super(key: key); @override _ParentState createState() => _ParentState(); } class _ParentState extends State<Parent> { String text = 'This have to be changed from the parent'; @override Widget build(BuildContext context) { return Container( child: ElevatedButton( onPressed: () { // 调用setState更新状态,触发组件重绘 setState(() { text = "父组件修改后的文本内容"; }); }, child: Child( test: text, ), ), ); } }
子组件文件代码
新增didUpdateWidget生命周期回调,监听父组件传递参数的变化,同步更新自身State:
class Child extends StatefulWidget { final String test; const Child({ @required this.test, Key key }) : super(key: key); @override _ChildState createState() => _ChildState(); } class _ChildState extends State<Child> with TickerProviderStateMixin<Child> { String test; @override void initState() { test = widget.test; super.initState(); } // 新增该生命周期,监听父组件传参变化 @override void didUpdateWidget(covariant Child oldWidget) { super.didUpdateWidget(oldWidget); // 父组件传递的test值变化时,同步更新自身State if (oldWidget.test != widget.test) { setState(() { test = widget.test; }); } } @override Widget build(BuildContext context) { return Container( child: Text(test), ); } }
方案2:直接使用父组件传递参数(适用于子组件仅展示、不修改test值的场景,代码更简洁)
如果子组件不需要自主修改test的值,完全可以删除自身State内重复定义的test变量,直接在build方法中使用widget.test读取父组件传递的参数。父组件调用setState更新后,子组件会自动重绘拿到最新值,无需额外添加生命周期处理:
子组件修改后代码(父组件代码和方案1完全一致)
class Child extends StatefulWidget { final String test; const Child({ @required this.test, Key key }) : super(key: key); @override _ChildState createState() => _ChildState(); } class _ChildState extends State<Child> with TickerProviderStateMixin<Child> { // 删除内部重复定义的test变量,也不需要在initState中赋值 @override Widget build(BuildContext context) { // 直接使用widget.test读取父组件传递的最新值 return Container( child: Text(widget.test), ); } }
内容的提问来源于stack exchange,提问作者Da2ny
相关产品推荐
相关产品推荐

