【问题标题】:React.js re-render behavior changes when list contents change列表内容更改时 React.js 重新渲染行为更改
【发布时间】: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() 被提升为父组件并且itemsdispatch 作为道具传递时,它同样有效。

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

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

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

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

任何建议将不胜感激。

【问题讨论】:

  • 在我看来,变量正在发生变异,而不是使用useState 存储和更新。您是否在自定义挂钩中使用 useState 来维护此数组?您是否使用了它在您的调度功能中提供的set 功能?
  • @Laurence 这是我的第一个想法。自定义钩子使用useReducer,并通过调度函数。 reducer 函数将数组包装在一个新对象中。此外,它会重新渲染,直到我开始分页。

标签: reactjs react-hooks


【解决方案1】:

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

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

现在很简单:

modifiedItem.isSelected = newValue;
return { data };

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-30
    • 1970-01-01
    • 2023-04-09
    • 2018-04-10
    • 2013-08-16
    • 2014-03-14
    • 2020-04-23
    • 2021-01-27
    相关资源
    最近更新 更多