这是一个有关使用钩子时可能导致性能下降的问题。useState
从react docs引用示例:
function Counter({initialCount}) {
const [count, setCount] = useState(initialCount);
return (
<>
Count: {count}
<button onClick={() => setCount(initialCount)}>Reset</button>
<button onClick={() => setCount(prevCount => prevCount + 1)}>+</button>
<button onClick={() => setCount(prevCount => prevCount - 1)}>-</button>
</>
);
}
React保证setState函数身份是稳定的,并且在重新渲染时不会改变。这就是为什么安全地从useEffect或useCallback依赖项列表中省略的原因。
我有两个有关的用法查询useState
:
identity is stable and won’t change on re-renders
意思anonymous
函数作为事件处理程序传递。即使setState identity is stable
React声称的是真的,难道不是每次重新渲染都会重新创建匿名函数吗?如果useCallback
用于定义备注函数并将其用作事件处理程序,会不会更有效?
什么是身份稳定的,并且在重新渲染后不会改变?
返回的函数useState
在渲染周期内不会更改。也就是说,在第一个渲染周期设置状态后,仍可以调用在第一个渲染周期返回的调度函数。这使您可以在任何时候使用分派功能来设置钩子,而无需在函数引用更改时刷新钩子。
useEffect(() => {
setCount(initialCount);
}, [ initialCount, setCount ]); // <--- setCount is not needed here
我可以看到每个按钮都有一个匿名函数作为事件处理程序传递。即使React声称的setState身份是稳定的,也不会在每次重新渲染时都重新创建匿名函数吗?
是的,箭头函数将在重新渲染时重建。另一种方法是用于useCallback
记忆回调,但是要付出什么代价?调用useCallback
的成本,记忆该回调的成本,构建对该回调的引用的成本以及在每个重新渲染的情况下检索该回调的成本都远远超过了在每个重新渲染的情况下简单构建函数的好处。
该useCallback
函数本身有20行,带有对其他内部React API的其他3个嵌套函数调用。所有这些都可以防止在每个渲染器上执行单行功能?数学加起来并没有useCallback
。唯一有用的情况是,您希望回调通过引用或其他某种方式具有“稳定的身份”,以便您可以将回调作为道具传递而不会引起过多的重新渲染。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句