即使道具没有改变,为啥还要对重新渲染组件做出反应?
Posted
技术标签:
【中文标题】即使道具没有改变,为啥还要对重新渲染组件做出反应?【英文标题】:Why react rerendres components even if props didn't changed?即使道具没有改变,为什么还要对重新渲染组件做出反应? 【发布时间】:2021-07-16 17:59:18 【问题描述】:我玩了一段时间的 react 并阅读了文档,我发现一些对我来说似乎很奇怪的东西,为什么即使子 props 相同,为什么在父级的每次状态更改时都会对组件的子元素进行重新渲染? ? 为什么我应该将我的组件包装在 Memo() 中以防止这种重新渲染? 让 Memo 成为每个 React 组件的默认值不是更好,还是应该将它用于我的所有组件。
【问题讨论】:
这就是 react 的工作原理。即使正在更新的状态没有传递给孩子,它也会重新呈现。如果您不想让孩子重新渲染,则需要使用备忘录。 相关:***.com/questions/61301937/… 【参考方案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 进行浅层比较,而对于功能组件,您使用 memo
、useMemo
(用于记忆值)和 useCallback
(用于记忆函数)。
【讨论】:
将组件包装在备忘录函数中总是好的吗?如果不是什么时候使用它? 当我将回调作为道具传递时,我会将我的组件包装在memo
中(然后回调必须包装在 useCallback 中)。每次父组件重新渲染时,它都会创建一个新的回调函数并将其发送给它的子组件。孩子“看到”了一个新功能(因为它是一个不同的对象)并重新渲染,因为一个新的道具来了。 useCallback
记忆回调函数,memo
将你的组件变成一个纯 FC,它将执行 props 的浅层比较。这是一个很好的resource【参考方案3】:
尝试在每次状态更改时使用 PureComponents 作为反应重新渲染,如果您的父组件重新渲染,那么您的所有子组件也将以相同的顺序重新渲染。为避免重新渲染子组件,您可以使用 React.Memo、useMemo 或 useCallback。虽然不是每次都记住组件。
【讨论】:
以上是关于即使道具没有改变,为啥还要对重新渲染组件做出反应?的主要内容,如果未能解决你的问题,请参考以下文章
当状态改变时,对文本字段做出反应 onChange 更新整个组件