为什么箭头函数在渲染之间没有被记忆?
Why arrow functions is not memoized between renders?
你能解释一下为什么 handleClick 函数总是新的吗?
function Foo() {
const handleClick = () => {
console.log('Click happened');
}
return <Button onClick={handleClick}>Click Me</Button>;
}
请记住,Foo()
也是一个 JavaScript 函数,已在每个渲染器上 re-run。
在那个函数里面有一个语句是:
const handleClick = () => {...};
意思:创建一个函数并将其赋值给我最近创建的局部变量handleClick
。因此,它将在每次渲染时重新创建。
这对性能的影响通常接近于零。但如果你需要,你可以为此进行优化。
const handleClick = useCallback(()=>{...},[dependencyArray]);
如果该函数依赖于可能发生变化的变量,您可以将它们添加到 dependencyArray
中,如果其中一个发生变化,React 将重新创建该函数。否则它将保留上次创建时的相同功能。
Are Hooks slow because of creating functions in render?
No. In modern browsers, the raw performance of closures compared to classes doesn’t differ significantly except in extreme scenarios.
发件人:https://reactjs.org/docs/hooks-reference.html#usecallback
useCallback()
Returns a memoized callback.
Pass an inline callback and an array of dependencies. useCallback will return a memoized version of the callback that only changes if one of the dependencies has changed. This is useful when passing callbacks to optimized child components that rely on reference equality to prevent unnecessary renders (e.g. shouldComponentUpdate).
() => { console.log('Click happened'); }
创建一个新函数。
在 Foo
函数调用之间,您没有采取任何措施来保留它。
所以每次调用Foo
,你都会得到一个新函数。
因为每次渲染 Foo
,它都会再次创建其中的所有内容。
// rendering Foo
function Foo() {
const handleClick = () => { // instantiated again
console.log('Click happened');
}
const something... // instantiated again
return <Button onClick={handleClick}>Click Me</Button>;
}
为了避免handleClick
再次被实例化,您可以在组件外部声明它。
const handleClick = () => {
console.log('Click happened');
}
function Foo() {
return <Button onClick={handleClick}>Click Me</Button>;
}
或者如果你真的希望它在函数的范围内但不被实例化,你可以这样做
// rendering Foo
function Foo() {
const handleClick = useCallback( // not re-defined again, uses old reference
() => {
console.log(`Click happened`);
}
);
const something... // instantiated again
return <Button onClick={handleClick}>Click Me</Button>;
}
你能解释一下为什么 handleClick 函数总是新的吗?
function Foo() {
const handleClick = () => {
console.log('Click happened');
}
return <Button onClick={handleClick}>Click Me</Button>;
}
请记住,Foo()
也是一个 JavaScript 函数,已在每个渲染器上 re-run。
在那个函数里面有一个语句是:
const handleClick = () => {...};
意思:创建一个函数并将其赋值给我最近创建的局部变量handleClick
。因此,它将在每次渲染时重新创建。
这对性能的影响通常接近于零。但如果你需要,你可以为此进行优化。
const handleClick = useCallback(()=>{...},[dependencyArray]);
如果该函数依赖于可能发生变化的变量,您可以将它们添加到 dependencyArray
中,如果其中一个发生变化,React 将重新创建该函数。否则它将保留上次创建时的相同功能。
Are Hooks slow because of creating functions in render?
No. In modern browsers, the raw performance of closures compared to classes doesn’t differ significantly except in extreme scenarios.
发件人:https://reactjs.org/docs/hooks-reference.html#usecallback
useCallback()
Returns a memoized callback.
Pass an inline callback and an array of dependencies. useCallback will return a memoized version of the callback that only changes if one of the dependencies has changed. This is useful when passing callbacks to optimized child components that rely on reference equality to prevent unnecessary renders (e.g. shouldComponentUpdate).
() => { console.log('Click happened'); }
创建一个新函数。
在 Foo
函数调用之间,您没有采取任何措施来保留它。
所以每次调用Foo
,你都会得到一个新函数。
因为每次渲染 Foo
,它都会再次创建其中的所有内容。
// rendering Foo
function Foo() {
const handleClick = () => { // instantiated again
console.log('Click happened');
}
const something... // instantiated again
return <Button onClick={handleClick}>Click Me</Button>;
}
为了避免handleClick
再次被实例化,您可以在组件外部声明它。
const handleClick = () => {
console.log('Click happened');
}
function Foo() {
return <Button onClick={handleClick}>Click Me</Button>;
}
或者如果你真的希望它在函数的范围内但不被实例化,你可以这样做
// rendering Foo
function Foo() {
const handleClick = useCallback( // not re-defined again, uses old reference
() => {
console.log(`Click happened`);
}
);
const something... // instantiated again
return <Button onClick={handleClick}>Click Me</Button>;
}