Flutter/Dart:我的小部件树中可以有多个带有状态的小部件吗?

Posted

技术标签:

【中文标题】Flutter/Dart:我的小部件树中可以有多个带有状态的小部件吗?【英文标题】:Flutter/Dart: Can I have multiple widgets with state in my Widgets tree? 【发布时间】:2021-04-12 01:38:23 【问题描述】:

我一直在想,为什么我必须在树中向下“提升”某些小部件的状态,以反映小部件 UI 中的变化。 我不能简单地拥有多个有状态的小部件吗?例如,将树中最低的有状态小部件导入到我的***小部件中,从那里我可以不只是调用我的小部件的一些方法来触发它的 setState() 方法,并且只是更新 DOM 树中的那个部分关心我的小部件?

其次,我必须将我的属性和其他重要部分从较低的小部件也向上移动到我的较高状态的小部件中,在我看来,React 有时会冒着使该类与不相关的功能和属性杂乱无章的风险只需传递适合的方法回调就更好了……

我的 Flutter 应用程序中是否始终只有一个有状态小部件处于***别?

【问题讨论】:

这就是为什么 Flutter 中的状态管理解决方案有这么多变体的原因。 您是否尝试制作多个具有自己状态的有状态小部件,并且您想要每个小部件的回调? 【参考方案1】:

父母无权访问子小部件/状态,只能反过来。所以你不能“将树下的最低状态小部件导入我的***小部件”

当您想在小部件树的不同分支之间共享该状态时,您只需要“提升状态”。然后子节点可以查找父节点并访问共享状态。

不要害怕StatefulWidget - 您可以根据需要使用任意数量

研究 Flutter 状态管理解决方案,这些解决方案的存在正是为了将事物分开(ChangeNotifier、Provider、BLOC、Redux 等)

【讨论】:

【参考方案2】:

我的小部件树中可以有多个带有状态的小部件吗?

答案是,是的,您可以在您的小部件中创建多个StatefulWidget。您还可以使用Function(yourcallback) 从最低的StatefulWidget 创建callback 函数。在我看来,flutter 也支持 component base model,并且尽可能动态地定制我们自己的 widget。

例如:

子小部件

子部件有它的状态。

class Child extends StatefulWidget 
  final int counter;
  final Function(int childCounter) callback; //here is your callback
  const Child(
    Key key,
    this.counter,
    this.callback,
  ) : super(key: key);
  @override
  _ChildState createState() => _ChildState();


class _ChildState extends State<Child> 
  String _childState = '';

  @override
  Widget build(BuildContext context) 
    return Container(
      color: Colors.green[400],
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          Text("Child"),
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              IconButton(
                  icon: Icon(Icons.exposure_minus_1_rounded),
                  onPressed: () 
                    this.widget.callback(this.widget.counter - 1); //here is your callback
                    setState(() 
                      _childState = "minus one";
                    );
                  ),
              IconButton(
                  icon: Icon(Icons.plus_one_rounded),
                  onPressed: () 
                    this.widget.callback(this.widget.counter + 1); //here is your callback
                    setState(() 
                      _childState = "plus one";
                    );
                  )
            ],
          ),
          Text(_childState)
        ],
      ),
    );
  

父小部件

父母从孩子那里得到回调。

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


class _ParentState extends State<Parent> 
  int _counter = 0;
  @override
  Widget build(BuildContext context) 
    return Scaffold(
      appBar: AppBar(
        title: Text("Multiple State"),
      ),
      body: Container(
        child: Column(
          children: [
            Child(
              counter: _counter,
              callback: (childCounter)  //here is callback from the child
                print(childCounter);
                setState(() 
                  _counter = childCounter;
                );
              ,
            ),
            Text("Parent"),
            Center(
              child: Text(_counter.toString()),
            )
          ],
        ),
      ),
    );
  

从其父级更改子级状态

你可以使用didUpdateWidget()here you can see the docs

【讨论】:

以上是关于Flutter/Dart:我的小部件树中可以有多个带有状态的小部件吗?的主要内容,如果未能解决你的问题,请参考以下文章

从原生 Android 主屏幕小部件调用 Flutter (Dart) 代码

如何在 Flutter (Dart) 中通过新路由获取子级 StreamProvider 数据

VS Code 和 Flutter/Dart,小部件自动完成功能不起作用

Gridview 中的小部件在离屏时丢失状态

颤振未找到材料小部件

Flutter / Dart:地图列表与小部件列表?哪个更好?