react-window 保存已删除行的状态
react-window saves state of deleted row
这是我的问题。
我正在使用 react-window 来呈现大型表格。每行都有自己的本地状态。我删除一行后,下一行向上移动并获得删除行的状态(this how it looks in my app)。
这个问题有解决办法吗?我可以使用 react-window 为每一行设置本地状态吗?
codesandbox example | gif how it works
这里有一个基本问题——react-window 将动态渲染、卸载和重新渲染组件。因此,如果您希望数据在重新渲染时保持不变 - 您必须通过道具和函数传递计数来更改它。将数据与项目数据本身一起存储。
我会尽快尝试展示一个工作演示,但是看看这个可以理解这段代码发生的另一个问题:https://codesandbox.io/s/react-window-row-state-problem-mmukt
我已将大小编辑为 150 而不是 50,这导致 window 获得滚动条。现在,尝试多次单击 "two"。这将增加计数。接下来,滚动到底部并返回。您会看到计数丢失了。
这是因为 react-window 挂载和卸载组件的方式。
为了在您的原始代码中解决此问题,我进行了以下修改:
1. 将 count/active 状态移动到父级。
2.将updateCount函数传给TableRow.
本质上,TableRow 现在是一个纯组件:)
这里是link:https://codesandbox.io/s/react-window-row-state-problem-uzsdl
希望对您有所帮助。
简而言之,你不能。问题是,当你删除一个项目时,之前用于它的相同组件将用于呈现它之后的项目(所以如果你删除第二个项目,第三个项目将使用 Row
来自旧的第二个元素)。它将保持该项目的状态。如果您添加一个 useEffect
来检测该项目已更改,那么您将破坏它之后的所有内容(因为所有内容都增加了一个,删除项目之后的所有项目都将重置其状态。您无权访问兄弟组件的状态,因此您无法传播状态。
这里有几个选项:
- 将选择添加到项目的属性,并提供更新项目的方法。
- 使选择状态成为
App
组件状态的一部分,并将其传递给组件,以便它可以适当地呈现。
我还要补充一点,您可能不想像现在这样在每次渲染时都映射到可能很大的项目列表。看起来你这样做是为了暴露 deleteItems
。我会推荐更多这样的东西:
<FixedSizeList
height={500}
width={300}
itemCount={items.length}
itemSize={50}
itemData={{items, deleteItem}}
>
{Row}
</FixedSizeList>
那么你的 Row
组件的 data
将同时具有 items
数组和 deleteItem
函数。如果您在 App
中维护选定的行状态,则可以轻松扩展它以将选定状态和修改功能向下传递到 Row
组件。
这是我的问题。
我正在使用 react-window 来呈现大型表格。每行都有自己的本地状态。我删除一行后,下一行向上移动并获得删除行的状态(this how it looks in my app)。
这个问题有解决办法吗?我可以使用 react-window 为每一行设置本地状态吗?
codesandbox example | gif how it works
这里有一个基本问题——react-window 将动态渲染、卸载和重新渲染组件。因此,如果您希望数据在重新渲染时保持不变 - 您必须通过道具和函数传递计数来更改它。将数据与项目数据本身一起存储。
我会尽快尝试展示一个工作演示,但是看看这个可以理解这段代码发生的另一个问题:https://codesandbox.io/s/react-window-row-state-problem-mmukt
我已将大小编辑为 150 而不是 50,这导致 window 获得滚动条。现在,尝试多次单击 "two"。这将增加计数。接下来,滚动到底部并返回。您会看到计数丢失了。
这是因为 react-window 挂载和卸载组件的方式。
为了在您的原始代码中解决此问题,我进行了以下修改: 1. 将 count/active 状态移动到父级。 2.将updateCount函数传给TableRow.
本质上,TableRow 现在是一个纯组件:)
这里是link:https://codesandbox.io/s/react-window-row-state-problem-uzsdl
希望对您有所帮助。
简而言之,你不能。问题是,当你删除一个项目时,之前用于它的相同组件将用于呈现它之后的项目(所以如果你删除第二个项目,第三个项目将使用 Row
来自旧的第二个元素)。它将保持该项目的状态。如果您添加一个 useEffect
来检测该项目已更改,那么您将破坏它之后的所有内容(因为所有内容都增加了一个,删除项目之后的所有项目都将重置其状态。您无权访问兄弟组件的状态,因此您无法传播状态。
这里有几个选项:
- 将选择添加到项目的属性,并提供更新项目的方法。
- 使选择状态成为
App
组件状态的一部分,并将其传递给组件,以便它可以适当地呈现。
我还要补充一点,您可能不想像现在这样在每次渲染时都映射到可能很大的项目列表。看起来你这样做是为了暴露 deleteItems
。我会推荐更多这样的东西:
<FixedSizeList
height={500}
width={300}
itemCount={items.length}
itemSize={50}
itemData={{items, deleteItem}}
>
{Row}
</FixedSizeList>
那么你的 Row
组件的 data
将同时具有 items
数组和 deleteItem
函数。如果您在 App
中维护选定的行状态,则可以轻松扩展它以将选定状态和修改功能向下传递到 Row
组件。