使用React的useCallback
钩子实际上只是useMemo
的包装,专门用于函数,以避免在组件的props中不断创建新的函数实例。我的问题来自何时需要将争论传递给基于备忘录创建的回调。
例如,像这样创建的回调...
const Button: React.FunctionComponent = props => {
const onClick = React.useCallback(() => alert('Clicked!'), [])
return <button onClick={onClick}>{props.children}</button>
}
是一个简单的示例回调,不需要任何外部值即可完成其工作。但是,如果我想为React.Dipatch<React.SetStateAction>
函数类型创建通用的备注回调,则它将需要参数...例如:
const Button: React.FunctionComponent = props => {
const [loading, setLoading] = React.useState(false)
const genericSetLoadingCb = React.useCallback((x: boolean) => () => setLoading(x), [])
return <button onClick={genericSetLoadingCb(!loading)}>{props.children}</button>
}
在我看来,这与执行以下操作完全相同...
const Button: React.FunctionComponent = props => {
const [loading, setLoading] = React.useState(false)
return <button onClick={() => setLoading(!loading)}>{props.children}</button>
}
这将使记住该功能的目的失效,因为它仍然会在每个渲染上创建一个新函数,因为genericSetLoadingCb(false)
也会在每个渲染上都返回一个新函数。
这种理解是正确的,还是用参数描述的模式仍然保持记忆的好处?
const genericSetLoadingCb = React.useCallback((x: boolean) => () => setLoading(x), [])
[您在上面所做的操作是确保在重新渲染时genericSetLoadingCb
保持相同。但是,请像这样从每次创建新功能时都选择:
genericSetLoadingCb(!loading)
每个渲染器上返回的函数将有所不同-因此没有备注。为了确保记住返回的函数,您需要类似以下内容:
let deleteSection = React.useCallback(
memoize((x: boolean) => () => setLoading(x)),
[]
);
例如,我使用快速记忆
import memoize from "fast-memoize";