gpt4 book ai didi

javascript - 为什么 `useCallback` 不能总是返回相同的 ref

转载 作者:行者123 更新时间:2023-12-03 09:32:18 24 4
gpt4 key购买 nike

我不明白为什么useCallback每次更新一个 deps 时总是返回一个新的 ref。它导致许多重新渲染 React.memo()本来可以避免的。useCallback 的这个实现有什么问题(如果有的话) ?

export function useCallback(callback) {

const callbackRef = useRef();

callbackRef.current = callback;

return useState(() =>
(...args) => callbackRef.current(...args)
)[0];

}
使用它而不是内置实现肯定会对性能产生重大的积极影响。
自己的结论:
没有理由不使用使用 ref 的实现而不是内置的 只要您知道其中的含义,即正如@Bergy 所指出的那样,您就不能存储回调以供以后使用(例如,在 setTimeout 之后)并期望回调具有与 if 相同的效果你会同步调用它。
然而,在我看来,这是首选行为,所以没有缺点🥂。
更新:
有一个 React RFC 用于引入一个内置的钩子(Hook)来做到这一点。它将被称为 useEvent

最佳答案

What is, if any, the problem with this implementation of useCallback?


我怀疑当有人存储对您的回调的引用以供以后使用时,它会产生意想不到的后果,因为它会改变它正在做的事情:

const { Fragment, useCallback, useState } = React;

function App() {
const [value, setValue] = useState("");
const printer = useCallback(() => value, [value]);
return <div>
<input type="text" value={value} onChange={e => setValue(e.currentTarget.value)} />
<Example printer={printer} />
</div>
}

function Example({printer}) {
const [printerHistory, setHistory] = useState([]);
return <Fragment>
<ul>{
printerHistory.map(printer => <li>{printer()}</li>)
}</ul>
<button onClick={e => setHistory([...printerHistory, printer])}>Store</button>
</Fragment>
}

ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://unpkg.com/react@16.14.0/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16.14.0/umd/react-dom.production.min.js"></script>
<div id="root"></div>

(当然,在这个简化的演示中, printer 回调只不过是对 value 本身的无用闭包,但您可以想象一个更复杂的情况,即可以选择一个单独的历史条目并希望使用复杂的 on-回调中的需求计算)
与原生 useCallback ,函数存储在 printerHistory将是对不同值的不同闭包,而在您的实现中,它们都是引用最新 useCallback 的相同函数参数并且仅在每次调用时打印当前值。

关于javascript - 为什么 `useCallback` 不能总是返回相同的 ref,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65890278/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com