【发布时间】:2021-03-24 16:44:17
【问题描述】:
这个问题需要一些背景知识才能理解:
我的应用使用具有布尔状态的各种项目列表,用户通过单击来切换。
我用两个可重用的元素实现了这个逻辑:
- 自定义挂钩
useSelections(),它维护{ id, name, isSelected }形式的对象数组,其中isSelected是布尔值,是唯一的可变元素。它将数组作为当前状态返回,以及一个分派函数,该函数接受{ id, newValue }形式的输入,并使用给定的id更新对象的isSelected成员 - 一个函数组件
Selector,它将单个项目和来自useSelections的调度作为道具,并返回一个<li>元素,其CSS类依赖于isSelected。
通常,它们以以下方式一起使用,效果很好(即,内部状态和列表项的颜色是同步的,并在单击时切换):
function localComponent(props) {
const [items, dispatch] = useSelections(props.data);
return (
<ul>
{items.map(item => <Selector key={item.id} item={item} onChange={dispatch} />)}
</ul>
);
}
当useSelections() 被提升为父组件并且items 和dispatch 作为道具传递时,它同样有效。
当数组变大时麻烦就开始了,我决定分页:
<ul>
{items.slice(start, end).map(item => <Selector key={item.id} item={item} onChange={dispatch} />)}
</ul>
(start 和 end 是组件状态的一部分。)
当我的组件第一次渲染时,它可以正常工作。但是,一旦 start 和 end 发生更改(移动到下一页),单击项目会更改内部状态,但不再触发重新渲染。在 UX 术语中,这意味着在第一次“下一步”单击之后,当我单击一个项目时,似乎什么也没有发生,但如果我再次单击“下一步”,然后“返回”,我刚刚单击的项目现在已经改变。
任何建议将不胜感激。
【问题讨论】:
-
在我看来,变量正在发生变异,而不是使用
useState存储和更新。您是否在自定义挂钩中使用useState来维护此数组?您是否使用了它在您的调度功能中提供的set功能? -
@Laurence 这是我的第一个想法。自定义钩子使用
useReducer,并通过调度函数。 reducer 函数将数组包装在一个新对象中。此外,它会重新渲染,直到我开始分页。
标签: reactjs react-hooks