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

标签 javascript reactjs react-hooks usecallback

我不明白为什么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/

相关文章:

javascript - 浏览器调整大小不影响 HTML 内容

javascript - Angular 服务变量不更新

reactjs - 使用 Enzyme 进行测试时使用 React Hooks 访问功能组件的状态

react native useState 错误 ("is read-only")

javascript - libphonenumber javascript - 验证

javascript - 使用 Javascript/jQuery 剥离转义字符

javascript - Reactjs中多个元素的切换状态

javascript - Rechart 响应容器不呈现

javascript - 简单的 Redux 应用程序,仅当我使用 mergeReducers 时 Counter 返回未定义

javascript - React、React Hooks、useEffect 内不同的 console.log 打印顺序