使用 React 钩子和备忘录时如何防止子组件重新渲染?

编程入门 行业动态 更新时间:2024-10-27 07:21:43
本文介绍了使用 React 钩子和备忘录时如何防止子组件重新渲染?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我刚开始尝试 React 钩子,我想知道如何防止子组件在父组件重新渲染时重新渲染.我正在寻找类似于在 componentDidUpdate 中返回 false 的内容.我的问题似乎源于我在子组件中调用的单击处理程序以更改父组件中的状态.由于该函数是在父组件中创建的,因此它会在每个父渲染上创建新的,这会触发子组件中的 prop 更改,然后导致子组件重新渲染(我认为).下面是一些示例代码来帮助说明这种情况.

function Parent() {const [item, setItem] = useState({ name: "item", value: 0 });const handleChangeItem = () =>{const newValue = item.value + 1;setItem({ ...item, value: newValue });};return <Child item={item} changeItem={handleChangeItem}/>;}const Child = React.memo(function Child({ item, changeItem }) {函数 handleClick(){更改项目();}返回 (<div>名称:{item.name} 值:{item.value}<button onClick={handleClick}>更改父级中的状态</button>

);});

每次父组件渲染时,如何防止子组件渲染?父级中的 handleChangeItem 是否应该位于其他地方,以便不会在每次渲染时重新创建?如果是这样,它如何访问 useState 返回的 item 和 setItem ?

我对反应还很陌生,刚刚开始玩钩子,所以我可能遗漏了一些明显的东西.

解决方案

在您的情况下,记住 Child 并没有真正意义,因为如果项目发生更改,则孩子必须重新渲染.但是,如果在 props 没有改变的情况下,但是由于函数被重新创建,孩子仍然在重新渲染,你可以使用 useCallback 钩子在每次渲染时记住函数.此外,由于您已经记住了处理程序,您应该使用回调方法来更新状态,因为处理程序内的 item 只会引用它在最初创建函数时的值

function Parent() {const [item, setItem] = useState({ name: "item", value: 0 });const handleChangeItem = useCallback(() => {setItem(prevItem => ({ ...prevItem, value: prevItem.value + 1 }));}, []);返回 (<>名称:{item.name} 值:{item.value}<Child changeItem={handleChangeItem}/></>);}const Child = React.memo(function Child({ item, changeItem }) {函数 handleClick() {更改项目();}console.log("子渲染");返回 (<div><button onClick={handleClick}>更改父级中的状态</button>

);});

工作演示

PS 感谢@danAbramov 的指导

I just started experimenting with React hooks and I'm wondering how I can prevent a child component from re-rendering when it's parent re-renders. I'm looking for something similar to returning false in componentDidUpdate. My issue seems to stem from the click handler I'm calling in the child component to change state in the parent component. Since the function is created in the parent component, it is created new on each parent render which triggers a prop change in the child component, which then causes the child to re-render (I think). Here is some sample code to help illustrate the situation.

function Parent() { const [item, setItem] = useState({ name: "item", value: 0 }); const handleChangeItem = () => { const newValue = item.value + 1; setItem({ ...item, value: newValue }); }; return <Child item={item} changeItem={handleChangeItem} />; } const Child = React.memo(function Child({ item, changeItem }) { function handleClick(){ changeItem(); } return ( <div> Name: {item.name} Value: {item.value} <button onClick={handleClick}>change state in parent</button> </div> ); });

How do I prevent Child component from rendering every time Parent component renders? Should handleChangeItem in the parent live someplace else so that it is not re-created on each render? If so, how does it get access to item and setItem returned by useState?

I'm pretty new to react and just started playing with hooks so I'm probably missing something obvious.

解决方案

In your case it doesn't really makes sense to memoize Child because if item changes, the child has to re-render. However if there is a case that props do not change , but still the child is re-rendering due to the functions getting recreated you would make use of useCallback hook to memoize the functions, on each render. Also since you have memoized the handler, you should make use of the callback method to update state since item inside the handler will only refer to the value it had when the function was initially created

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

Working demo

P.S. Credit to @danAbramov for the direction

更多推荐

使用 React 钩子和备忘录时如何防止子组件重新渲染?

本文发布于:2023-06-04 08:38:18,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/493391.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:钩子   备忘录   组件   如何防止   React

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!