为什么 React 组件在属性没有变化时也会重新渲染?

3
我已经玩了一段时间的React并阅读了文档,发现一个问题让我感到奇怪,为什么在父组件状态改变时,即使子组件的属性相同,React也会重新渲染子元素? 为了防止这种重新渲染,为什么应该将组件包装在Memo()中呢? 是否应该将Memo作为每个React组件的默认选项,或者是否应该对所有组件都使用它呢?

这就是React的工作原理。即使状态被更新,但如果没有传递给子组件,它仍会重新渲染。如果您不希望子组件重新渲染,您需要使用memo。 - FireFighter
相关:https://dev59.com/Orroa4cB1Zd3GeqPknXX - Ciro Santilli OurBigBook.com
3个回答

0

memo 是 PureComponent 在函数组件中的实现。PureComponent 在类组件中执行浅比较,而在函数组件中,你可以使用 memouseMemo(将值进行记忆)以及 useCallback(将函数进行记忆)。


将组件包装在memo函数中总是好的吗?如果不是,什么时候使用它? - T.arar
如果我将回调函数作为props传递时,就会使用memo包装我的组件(回调函数必须在useCallback中进行包装)。每次父组件重新渲染时,它都会创建一个新的回调函数并将其发送到其子级。子级“看到”一个新函数(因为它是一个不同的对象),并且重新渲染,因为出现了一个新的属性。useCallback可以缓存回调函数,而memo可以将您的组件转换为Pure FC,以执行浅比较属性。这里有一个很好的[资源] (https://dmitripavlutin.com/use-react-memo-wisely/)。 - Andrii Lukianenko

0

尝试使用PureComponents,因为在状态改变时React会重新渲染,如果您的父组件重新渲染,则所有子组件也将按相同顺序重新渲染。为了避免重新渲染子组件,您可以使用React.Memo、useMemo或useCallback。虽然不是每次都将组件记忆化。


0

在每次状态改变时,React都会触发渲染函数,进而调用其子组件进行重新渲染,请参考以下示例来解决您的问题,或访问https://www.robinwieruch.de/react-prevent-rerender-component

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>
 );
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接