当列表内容改变时,React.js 重新渲染行为改变

时间:2021-03-24 16:44:17

标签: reactjs react-hooks

这个问题需要一些背景知识才能理解:

我的应用使用用户通过点击切换的布尔状态的各种项目列表。

我用两个可重用的元素实现了这个逻辑:

  • 一个自定义钩子 useSelections(),它维护一个 { id, name, isSelected } 形式的对象数组,其中 isSelected 是布尔值并且是唯一的可变元素。它将数组作为当前状态返回,并返回一个调度函数,该函数接受 { id, newValue } 形式的输入并使用给定的 isSelected
  • 更新对象的 id 成员
  • 一个函数组件 Selector,它将单个项目和来自 useSelections 的分派作为 props,并返回一个 <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() 被提升为父组件并且 itemsdispatch 作为 props 传递时,它同样有效。

当数组变大时麻烦就开始了,我决定分页:

<ul>
   {items.slice(start, end).map(item => <Selector key={item.id} item={item} onChange={dispatch} />)}
</ul>

startend 是组件状态的一部分。)

当我的组件第一次被渲染时,它可以正常工作。但是,一旦 startend 被更改(移动到下一页),点击一个项目会改变内部状态,但不再触发重新渲染。在 UX 术语中,这意味着在第一次“下一个”点击之后,当我点击一个项目时,似乎什么也没有发生,但是如果我再次点击“下一个”,然后“返回”,我刚刚点击的项目现在已经改变了。

如有任何建议,我们将不胜感激。

1 个答案:

答案 0 :(得分:0)

我通过从 reducer 函数中删除逻辑来忽略没有变化的调用来解决这个问题:

const hasChanged = modifiedItem.isSelected !== newValue;
modifiedItem.isSelected = newValue;
return hasChanged ? { data } : state;

现在只是:

modifiedItem.isSelected = newValue;
return { data };

这里的 React 仍有一些我不明白的地方,但我眼前的问题已经解决了。