5

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

我们有一个子组件列表,每个子组件称为NumChoice,每个代表一个数字。NumChoice被包裹在React.memo. 在父组件中,我们有一个布尔数组choices,每个对应一个子组件NumChoice。起初, 的所有元素choices都是false。为了渲染子组件,我们遍历choices,并为每个选择生成相应的子组件NumChoicechooseDivisibles我们在父组件中定义一个函数,使用useCallback从每个子组件调用的函数NumChoicechooseDivisibles获取调用者的索引NumChoice并将相应的元素更改为choicesto true。如果NumChoice其对应的元素在choicestrue,否则,其背景颜色为“白色”。

完整代码位于: https ://codesandbox.io/s/react-rerender-l4e3c?fontsize=14&hidenavigation=1&theme=dark

包裹NumChoiceinReact.memochooseDivisiblesin useCallback,我们希望只重新渲染NumChoice相应元素发生choices变化的组件,但 React 会重新渲染它们。chooseDivisibles被包裹在 中,除了 .useCallback之外没有列出任何依赖项setChoices。此外,NumChoice被包裹起来React.memo,它应该只在指定的道具发生变化时重新渲染,但它们没有变化,并且变化choices不应该对重新渲染有任何影响NumChoice。如果我们排除检查上一个和下一个道具的相等性chooseDivisibles,它会按预期工作,但我认为上一个和下一个的比较chooseDivisibles不应该影响重新渲染NumChoice,因为它被包裹在useCallback并且不依赖于choices. 我们如何防止重新渲染NumChoiceprops未更改的组件?

4

1 回答 1

1

啊,我看到NumChoice.js我们也在断言prevProps.chooseDivisibles === nextProps.chooseDivisibles,它总是false,因为chooseDivisibles={event => chooseDivisibles(idx)}每次都会生成一个新函数

如果你删除prevProps.chooseDivisibles === nextProps.chooseDivisibles,它只会重新渲染受影响的!

于 2020-03-04T18:17:53.827 回答