如何仅更新小部件的一部分?

时间:2020-12-23 11:34:31

标签: flutter bloc

我有一个实体对象,为简单起见,我们现在称其为 Todo。我想要一个小部件,我可以在其中同时编辑多个这些待办事项,例如 EditableTodoList(这将显示 EditableTodo 的列表)。 这个小部件会收到一个 List<Todo> 以及类似 Function onTodoEdited(Todo) 的东西。 我正在尝试使用不可变数据,因此当正在编辑 EditableTodo 时(并且事件被传播到包含 EditableTodoList 的小部件),我会创建一个新的 List<Todo>包含更新后的 Todo,但随后 EditableTodoList 将重建其所有 EditableTodo

我该如何优化,只重建相关的 EditableTodo?我不想修改道具原始 List<Todo>,因为这隐藏了一个重要的细节。

背景:当前状态在一肘内,我对每个 context.select 列表项都 EditableTodo-ing 状态中相应的 Todo,这样只有编辑过的项目会重建。我想将这个 EditableTodoList 与肘分开。

理论上我认为这是不可能的,因为 EditableTodoList 被赋予了新的属性,所以它必须重建,这意味着所有的子树都会被重建。 EditableTodo 不能是 const,因为它的 prop 不是常量。 但是,将 EditableTodoList 与肘分开的最优雅的方法是什么?由于它只需要一个 List<Todo> 来显示,因此应该可以以某种方式优化未更改的 Todos

的呈现

1 个答案:

答案 0 :(得分:1)

您应该考虑小部件、元素和渲染树的工作方式,以便关注。关于 Flutter 的渲染机制有一个很棒的 video。重建树时,仅使用 compares 和运行时类型值构建 key 两个小部件。这意味着如果您更改 Text 小部件的字符串值,将再次使用具有变异数据的相同渲染对象。不会创建新的渲染对象,这意味着渲染树上不会发生不必要的重建。与渲染树相比,重建小部件树并不昂贵。

<块引用>

如果两个小部件的 runtimeTypekey 属性是 operator==,则新小部件替换旧小部件 通过更新底层元素(即,通过调用 Element.update 使用新的小部件)。否则,旧元素将从 树,新的小部件被膨胀成一个元素,新的元素 被插入到树中。

最小化 ListView 中的构建范围是有限制的。 ListView 本身应该重建以更改元素。所以你不能在重建时定位列表中的特定元素。因此,不可变集合在此上下文中无关紧要,因为框架不关心值,而关心键和运行时类型。您可以传递一个完全修改过的列表,也可以只更改一个元素,这将具有相同的效果。

如果您担心每次修改单个 Todo 时都会创建新的渲染对象,请不要担心,根本没有。框架通过“回收”渲染对象来帮助您。

相关问题