Difference between useCallback and useRef hooks when useRef is used as an instance variable
我正在阅读有关React中的钩子的信息,并且在理解useRef和useCallback钩子之间的区别时遇到了一些麻烦。
具体地说,我想了解如何使用这两个方法来避免不必要地重新渲染子组件。
基于我对堆栈溢出的答案的理解,可以将以下函数编写为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | const Avatar = function({ history, url, fullName }) { const onMenuItemClick = urlToNavigate => history.push(urlToNavigate), onMenuItemClickRef = useRef(onMenuItemClick); return ( <Menu label={<RoundedImage src={url} alt={fullName} />} items={[ { label: `Logged in as: ${fullName}` }, { label:"Liked articles", onClick: () => onMenuItemClickRef.current("/liked-articles") }, { label:"Edit profile", onClick: () => onMenuItemClickRef.current("/profile") }, { label:"Logout", onClick: () => console.log("Logging out") } ]} /> ); }; |
替换是否也有意义:
1 | const onMenuItemClick = urlToNavigate => history.push(urlToNavigate) |
具有:
1 | const onMenuItemClick = useCallBack(urlToNavigate => history.push(urlToNavigate), [urlToNavigate]) |
是否仅在urlToNavigate更改时更改?
在问题中引用的链接中,关键是记住了子组件(接收回调的组件)。
在正常的"父代">"子代"周期中,每次"父代"的道具更改都会重新渲染,即使子代的任何道具都没有更改,子代也会重新渲染。
如果我们希望避免在不更改其prop的情况下渲染Child,则我们可以记住该组件(React.memo)。一旦这样做,我们可能会遇到一个问题,如果在Parent中为每个渲染创建一个函数回调,因为记忆的Children将被解释为一个新函数,因此将再次渲染。
为避免这种情况,我们可以在Parent中使用
在未记忆孩子的情况下使用
关于使用
不,这不起作用。您只能记住来自外部作用域的值,但是
您的回调具有
1 | const onMenuItemClick = useCallback(urlToNavigate => history.push(urlToNavigate), [history]) |
这样,不会在每个渲染器上都重新创建回调,而仅在