关于useCallback钩子和匿名函数的问题
Questions about useCallback hook and anonymous function
传递回调函数时,尤其是传递 参数化 函数时,我知道我应该使用 useCallback
挂钩,因为使用匿名函数会产生不利影响性能。
我说的匿名函数的例子是这样的
import React, { useState } from 'react';
const Component = () => {
const [param, setParam] = useState('');
...
return (
...
<SomeComponent
onClick={() => setParam('parameter')}
{...others}
/>
);
}
在将匿名函数转换为使用此钩子的过程中,我遇到了一个错误'Too many renders'或者没有正常工作。
但是具体是在什么情况下,在什么情况下我也不清楚
我使用了如下的 useCallback
。
import React, { useState, useCallback } from 'react';
const Component = () => {
const [param, setParam] = useState('');
const handleClick = useCallback((params) => {
setParam(params);
},[]);
...
return (
...
<SomeComponent
onClick={handleClick('parameter')}
{...others}
/>
);
}
然而,当在 useCallback
中使用匿名函数 return 时,它也有效。
这意味着这里的代码。 (仅与上述代码相比的差异。)
const handleClick = useCallback((params) => {
return () => setParam(params);
},[]);
在这种情况下,我想知道如果我只是使用匿名函数而不是使用这个钩子,是否比在 useCallback
中使用匿名函数更糟糕。
在您的代码中:
const handleClick = useCallback((params) => {
setParam(params);
},[]);
您应该像这样将参数传递到 useCallback
的第二个参数中:
const handleClick = useCallback((params) => {
setParam(params);
},[setParam,param, SETPARAMACTUALVALUE]);
// Change SETPARAMACTUALVALUE to whatever the variable name is for the `setParam` hook
useCallback hook 如果你想在 hook 的依赖关系改变之前保存函数会更好。它为您提供更好的性能,因为挂钩会记住内部函数。
const handleClick = useCallback((params) => {
setParam(params);
},[]);
...
return (
...
<SomeComponent
onClick={handleClick('parameter')}
{...others}
/>
);
在上面的代码中,在第一次渲染期间,在这个语句 "onClick={handleClick('parameter')}"
handleClick 函数中调用了一个名为 "parameter" 的字符串。因为 handleClick 有 setParam("parameter"),它会更新状态。更新状态将导致重新渲染,这将再次出现相同的语句 "onClick={handleClick('parameter')}"
导致无限循环。
您稍后添加的以下代码可以工作,因为您没有更新状态,而是 return 调用一个函数,该函数充当 onclick 处理程序。
const handleClick = useCallback((params) => {
return () => setParam(params);
},[]);
更好的方法如下,
import React, { useState, useCallback } from 'react';
const Component = () => {
const [param, setParam] = useState('');
const handleClick = useCallback((params) => {
setParam(params);
},[]);
...
return (
...
<SomeComponent
onClick={handleClick}
{...others}
/>
);
}
回到您的问题,比较性能取决于其他函数定义和 您组件内 return 函数内的子组件 的渲染时间。
假设您的应用程序中有另一个名为 'anotherHandleClick' 的 onclickHanldier。
那么你的组件看起来像这样
const Component = () => {
const [param, setParam] = useState('');
const [anotherParam, setAnotherParam] = useState('');
const handleClick = (params) => {
setParam(params);
};
const anotherHandleClick =(params) => {
setAnotherParam(params);
};
...
return (
...
<SomeComponent
onClick={handleClick('parameter')}
{...others}
/>
<SomeComponent
onClick={antherHandleClick('parameter')}
{...others}
/>
);
}
在上面的组件中,当 "SomeCompoenent" 中的任何一个被点击时,整个 "Component" 重新渲染,所以处理函数是新的 defined.and 当两者都对 onclick 进行引用相等性检查时处理函数,他们认为是新的处理函数使他们同时呈现两者。
在这种情况下,最好使用 useCallBack 钩子,如下所示,
const Component = () => {
const [param, setParam] = useState('');
const [anotherParam, setAnotherParam] = useState('');
const handleClick = useCallback((params) => {
setParam(params);
},[]);
const anotherHandleClick = useCallback((params) => {
setAnotherParam(params);
},[]);
...
return (
...
<SomeComponent
onClick={handleClick('parameter')}
{...others}
/>
<SomeComponent
onClick={antherHandleClick('parameter')}
{...others}
/>
);
}
在上面的代码中,当任何一个被点击时,状态都会改变。然后在渲染时,useCallback 确保 onclick 处理程序引用没有改变。因此不会重新呈现对 onclick 处理程序的依赖。
所以最后的想法是 它在两种情况下都在每个渲染器上创建一个函数。第二个(因为它被包装在 useCallback 中)将 return 在初始渲染时创建的记忆函数
何时使用 useMemo 或 useCallback refer this
传递回调函数时,尤其是传递 参数化 函数时,我知道我应该使用 useCallback
挂钩,因为使用匿名函数会产生不利影响性能。
我说的匿名函数的例子是这样的
import React, { useState } from 'react';
const Component = () => {
const [param, setParam] = useState('');
...
return (
...
<SomeComponent
onClick={() => setParam('parameter')}
{...others}
/>
);
}
在将匿名函数转换为使用此钩子的过程中,我遇到了一个错误'Too many renders'或者没有正常工作。 但是具体是在什么情况下,在什么情况下我也不清楚
我使用了如下的 useCallback
。
import React, { useState, useCallback } from 'react';
const Component = () => {
const [param, setParam] = useState('');
const handleClick = useCallback((params) => {
setParam(params);
},[]);
...
return (
...
<SomeComponent
onClick={handleClick('parameter')}
{...others}
/>
);
}
然而,当在 useCallback
中使用匿名函数 return 时,它也有效。
这意味着这里的代码。 (仅与上述代码相比的差异。)
const handleClick = useCallback((params) => {
return () => setParam(params);
},[]);
在这种情况下,我想知道如果我只是使用匿名函数而不是使用这个钩子,是否比在 useCallback
中使用匿名函数更糟糕。
在您的代码中:
const handleClick = useCallback((params) => {
setParam(params);
},[]);
您应该像这样将参数传递到 useCallback
的第二个参数中:
const handleClick = useCallback((params) => {
setParam(params);
},[setParam,param, SETPARAMACTUALVALUE]);
// Change SETPARAMACTUALVALUE to whatever the variable name is for the `setParam` hook
useCallback hook 如果你想在 hook 的依赖关系改变之前保存函数会更好。它为您提供更好的性能,因为挂钩会记住内部函数。
const handleClick = useCallback((params) => {
setParam(params);
},[]);
...
return (
...
<SomeComponent
onClick={handleClick('parameter')}
{...others}
/>
);
在上面的代码中,在第一次渲染期间,在这个语句 "onClick={handleClick('parameter')}"
handleClick 函数中调用了一个名为 "parameter" 的字符串。因为 handleClick 有 setParam("parameter"),它会更新状态。更新状态将导致重新渲染,这将再次出现相同的语句 "onClick={handleClick('parameter')}"
导致无限循环。
您稍后添加的以下代码可以工作,因为您没有更新状态,而是 return 调用一个函数,该函数充当 onclick 处理程序。
const handleClick = useCallback((params) => {
return () => setParam(params);
},[]);
更好的方法如下,
import React, { useState, useCallback } from 'react';
const Component = () => {
const [param, setParam] = useState('');
const handleClick = useCallback((params) => {
setParam(params);
},[]);
...
return (
...
<SomeComponent
onClick={handleClick}
{...others}
/>
);
}
回到您的问题,比较性能取决于其他函数定义和 您组件内 return 函数内的子组件 的渲染时间。 假设您的应用程序中有另一个名为 'anotherHandleClick' 的 onclickHanldier。 那么你的组件看起来像这样
const Component = () => {
const [param, setParam] = useState('');
const [anotherParam, setAnotherParam] = useState('');
const handleClick = (params) => {
setParam(params);
};
const anotherHandleClick =(params) => {
setAnotherParam(params);
};
...
return (
...
<SomeComponent
onClick={handleClick('parameter')}
{...others}
/>
<SomeComponent
onClick={antherHandleClick('parameter')}
{...others}
/>
);
}
在上面的组件中,当 "SomeCompoenent" 中的任何一个被点击时,整个 "Component" 重新渲染,所以处理函数是新的 defined.and 当两者都对 onclick 进行引用相等性检查时处理函数,他们认为是新的处理函数使他们同时呈现两者。 在这种情况下,最好使用 useCallBack 钩子,如下所示,
const Component = () => {
const [param, setParam] = useState('');
const [anotherParam, setAnotherParam] = useState('');
const handleClick = useCallback((params) => {
setParam(params);
},[]);
const anotherHandleClick = useCallback((params) => {
setAnotherParam(params);
},[]);
...
return (
...
<SomeComponent
onClick={handleClick('parameter')}
{...others}
/>
<SomeComponent
onClick={antherHandleClick('parameter')}
{...others}
/>
);
}
在上面的代码中,当任何一个被点击时,状态都会改变。然后在渲染时,useCallback 确保 onclick 处理程序引用没有改变。因此不会重新呈现对 onclick 处理程序的依赖。
所以最后的想法是 它在两种情况下都在每个渲染器上创建一个函数。第二个(因为它被包装在 useCallback 中)将 return 在初始渲染时创建的记忆函数
何时使用 useMemo 或 useCallback refer this