React:如何防止在`map`中重新渲染子组件?

时间:2020-03-04 15:03:13

标签: reactjs array-map rerender usecallback react-memo

我试图将问题简化为一个尽可能简单的例子:

我们有一个子组件列表,每个子组件称为NumChoice,每个子组件代表一个数字。 NumChoice包装在React.memo中。在父组件中,我们有一个布尔数组choices,每个布尔数组对应于一个子组件NumChoice。首先,choices的所有元素都是false。要渲染子组件,我们迭代choices,并为每个选择生成相应的子组件NumChoice。我们使用在每个子组件chooseDivisibles中调用的useCallback在父组件中定义一个函数NumChoicechooseDivisibles获取调用它的NumChoice的索引,并将choices的相应元素更改为true。如果每个NumChoicechoices中的对应元素为true,则其背景颜色为“红色”。否则,其背景颜色为“白色”。

完整的代码可在以下位置获得: https://codesandbox.io/s/react-rerender-l4e3c?fontsize=14&hidenavigation=1&theme=dark

包装NumChoice中的React.memochooseDivisibles中的useCallback,我们希望仅重新渲染NumChoice的相应元素发生变化的choices组件, React将它们全部重新渲染。 chooseDivisibles包装在useCallback中,其中除setChoices之外没有列出任何依赖项。此外,NumChoice被包装在React.memo中,并且仅当指定的props改变时才应重新渲染,但它们不会改变,并且更改choices对重新渲染NumChoice不会有任何影响。如果我们排除检查上一个道具和下一个道具中的chooseDivisibles的相等性,它会按预期工作,但是我认为比较上一个chooseDivisibles和下一个NumChoice不会影响重新渲染useCallback,因为包装在choices中,并且不依赖于NumChoice。如何防止重新渲染props不变的val prop = SimpleStringProperty() val baseList = listOf("a", "aa", "aaa", "b", "bb", "bbb") val filteredList = SortedFilteredList(baseList).apply { filterWhen(prop) {prop, item -> (prop?.length ?: 0) <= item.length} } 组件?

1 个答案:

答案 0 :(得分:1)

啊,我发现在NumChoice.js中我们还声明了prevProps.chooseDivisibles === nextProps.chooseDivisibles,它始终是false,因为chooseDivisibles={event => chooseDivisibles(idx)}每次都会生成一个新函数

如果您删除prevProps.chooseDivisibles === nextProps.chooseDivisibles,它将仅重新呈现受影响的对象!