useCallback
对于记忆要传递给子组件的函数很有用,但是如果你在循环中渲染这些子组件怎么办?例如
const setBlockedDate = useCallback(idx => ev => {
setBlockedDates(bd => arraySplice(bd,idx,1,[ev.value]));
},[setBlockedDates])
...
{blockedDates.map((bd,idx) => <VehicleBlockedDate
key={bd[REACT_KEY]}
defaultValue={bd}
onChange={setBlockedDate(idx)}
onDelete={deleteBlockedDate(idx)}
reasons={[]}/>)}
useCallback
只会记住外部功能,而不会记住内部功能。此模式是否有帮助程序函数?因为我认为这是不对的:
const setBlockedDate = useCallback(idx => useCallback(ev => {
setBlockedDates(bd => arraySplice(bd,idx,1,[ev.value]));
},[setBlockedDates]),[setBlockedDates])
我认为这是正确的:
function useArrayCallback(fn, deps = []) {
return useMemo(() => memoize(idx => (...args) => fn(idx, ...args)), deps);
}
memoize
在哪里:
function memoize(fn, options={
serialize: fn.length === 1 ? x => x : (...args) => JSON.stringify(args),
}) {
const cache = new Map();
return (...args) => {
const key = options.serialize(...args);
if(cache.has(key)) {
return cache.get(key);
}
const value = fn(...args);
cache.set(key, value);
return value;
}
}
或者您可以使用一些花哨的裤子预建记忆功能。
那么原题中的回调可以写成:
const setBlockedDate = useArrayCallback((idx,ev) => {
setBlockedDates(bd => arraySplice(bd,idx,1,[ev.value]));
})