我试图将问题简化为一个尽可能简单的例子:
我们有一个子组件列表,每个子组件称为NumChoice
,每个子组件代表一个数字。 NumChoice
包装在React.memo
中。在父组件中,我们有一个布尔数组choices
,每个布尔数组对应于一个子组件NumChoice
。首先,choices
的所有元素都是false
。要渲染子组件,我们迭代choices
,并为每个选择生成相应的子组件NumChoice
。我们使用在每个子组件chooseDivisibles
中调用的useCallback
在父组件中定义一个函数NumChoice
。 chooseDivisibles
获取调用它的NumChoice
的索引,并将choices
的相应元素更改为true
。如果每个NumChoice
在choices
中的对应元素为true
,则其背景颜色为“红色”。否则,其背景颜色为“白色”。
完整的代码可在以下位置获得: https://codesandbox.io/s/react-rerender-l4e3c?fontsize=14&hidenavigation=1&theme=dark
包装NumChoice
中的React.memo
和chooseDivisibles
中的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}
}
组件?
答案 0 :(得分:1)
啊,我发现在NumChoice.js
中我们还声明了prevProps.chooseDivisibles === nextProps.chooseDivisibles
,它始终是false
,因为chooseDivisibles={event => chooseDivisibles(idx)}
每次都会生成一个新函数
如果您删除prevProps.chooseDivisibles === nextProps.chooseDivisibles
,它将仅重新呈现受影响的对象!