【问题标题】:Why react rerendres components even if props didn't changed?即使道具没有改变,为什么还要对重新渲染组件做出反应?
【发布时间】:2021-07-16 17:59:18
【问题描述】:

我玩了一段时间的 react 并阅读了文档,我发现一些对我来说似乎很奇怪的东西,为什么即使子 props 相同,为什么在父级的每次状态更改时都会对组件的子元素进行重新渲染? ? 为什么我应该将我的组件包装在 Memo() 中以防止这种重新渲染? 让 Memo 成为每个 React 组件的默认值不是更好,还是应该将它用于我的所有组件。

【问题讨论】:

  • 这就是 react 的工作原理。即使正在更新的状态没有传递给孩子,它也会重新呈现。如果您不想让孩子重新渲染,则需要使用备忘录。

标签: javascript reactjs


【解决方案1】:

在每次状态变化时,react 都会触发一个 render 函数,该函数会调用其子组件来 rerender,请找到以下示例来解决您的问题,或访问 @987654321 @

function Parent() {
const [item, setItem] = useState({ name: "item", value: 0 });

const handleChangeItem = useCallback(() => {
  setItem(prevItem => ({ ...prevItem, value: prevItem.value + 1 }));
}, []);

return (
 <>
   Name: {item.name} Value: {item.value}
   <Child changeItem={handleChangeItem} />
 </>
 );
}

const Child = React.memo(function Child({ item, changeItem }) {
 function handleClick() {
   changeItem();
 }
console.log("child render");
return (
   <div>
    <button onClick={handleClick}>change state in parent</button>
   </div>
 );
});

【讨论】:

    【解决方案2】:

    memo 是 PureComponent 的实现,但用于功能组件。 PureComponent 会对类组件中的 props 进行浅层比较,而对于功能组件,您使用 memouseMemo(用于记忆值)和 useCallback(用于记忆函数)。

    【讨论】:

    • 将组件包装在备忘录函数中总是好的吗?如果不是什么时候使用它?
    • 当我将回调作为道具传递时,我会将我的组件包装在 memo 中(然后回调必须包装在 useCallback 中)。每次父组件重新渲染时,它都会创建一个新的回调函数并将其发送给它的子组件。孩子“看到”了一个新功能(因为它是一个不同的对象)并重新渲染,因为一个新的道具来了。 useCallback 记忆回调函数,memo 将你的组件变成一个纯 FC,它将执行 props 的浅层比较。这是一个很好的resource
    【解决方案3】:

    尝试在每次状态更改时使用 PureComponents 作为反应重新渲染,如果您的父组件重新渲染,那么您的所有子组件也将以相同的顺序重新渲染。为避免重新渲染子组件,您可以使用 React.Memo、useMemo 或 useCallback。虽然不是每次都记住组件。

    【讨论】:

      猜你喜欢
      • 2019-03-14
      • 1970-01-01
      • 2019-02-08
      • 2019-07-26
      • 2023-02-09
      • 1970-01-01
      • 1970-01-01
      • 2021-01-19
      相关资源
      最近更新 更多