【问题标题】:Is there a way to define a hook in a for?有没有办法在 for 中定义一个钩子?
【发布时间】:2021-05-14 03:26:01
【问题描述】:

为了更多的优化/通用逻辑,我想制作一个使用多个 useCallback 的好 useSelectors

这里的useSeletors 是在useReducer 上创建选择器(就像在redux 中一样)。 所以这是我的代码:

const useSelectors = (state, selectors) => useMemo(
    () => selectors.map(selector => 
        (...args) => (selector(state, ...args))
    ), 
    [state]
);

我想做的是:

const useSelectors = (state, selectors) => useMemo(
    () => selectors.map(selector => useCallback(
        (...args) => (selector(state, ...args))), 
        [state]
    ), 
    [state]
);

这实际上导致了错误。 我可能可以这样做:

const useSelectors = (state, selectors) => useMemo(
    () => selectors.map(selector => selector(state)), 
    [state]
);

但我无法在选择器函数中使用参数。
也许这不是问题,因为有一些我还不明白,关于useCallback :
如果我使用useCallback 而不给出参数但给出依赖,它几乎就像一个变量。
在我第一次调用它时,它被执行了吗?下一次(不更新依赖),我直接得到函数的返回而不执行?

如果我在回调中放入可变参数(例如计数器)会发生什么?
即使依赖项没有改变,它是否可能会使用这个新参数重新执行函数?
那么useCallback 结构是否对参数变得无用了?

我想问的最后一点是:何时执行回调?
对于useMemo,函数第一次在声明时执行? (或者我们第一次使用它的变量? => 这种情况的区别并不重要。)
useCallback 只有在代码或声明中使用() 调用时才被调用?
示例:

const myVar = useMemo(() => 5+5, [dependency]); // executed
const myFunc = useCallback(() => 5+5, [dependency]);

myVar; // 10
myFunc(); // executed => 10

myVar; // 10
myFunc(); // 10

因此,如果它像这样工作,最好在useMemo 中调用useCallBack,仅在调用选择器时执行选择器,而不是在我的第三个解决方案中的挂载处。
这就是为什么我想在我的钩子中使用多个useCallbacks,而不知道数字的主要原因。

[编辑]

useCallback 的第二个命题没有意义,因为:

const test = useCallback(() => {
        console.log('test is executed');
        return 'test';
    }, [state]);
    console.log(test());
    console.log(test());

日志:

测试已执行
测试
测试已执行
测试

并不是我所期望的:

测试已执行
测试
测试

所以它不能比第一个做得更好

【问题讨论】:

    标签: javascript reactjs react-hooks reducers


    【解决方案1】:

    useCallback 返回一个函数。当该钩子的依赖项之一(例如,某个计数器)发生更改时,useCallback 再次调用并返回新函数。这是因为传递给useCallback 的函数在useCallback 再次重新执行之前不知道计数器已更改。

    useMemo 的工作原理相同,但它返回一个值。理论上,您可以使用useMemo 实现useCallback,返回函数而不是值。我的意思是useCallback(fn, deps)useMemo(() => fn, deps) 相同。

    您可以在 React docs 中阅读有关它的更多信息。

    在您的代码中,您应该使用useMemo,并且不要在useMemo 中使用useCallback,因为您会收到一个错误并且它不是不必要的,因为它在将回调传递给依赖于优化的子组件时使用引用相等性以防止不必要的渲染。这不是你的情况。您的第一个代码示例是正确的。

    【讨论】:

    • 我已经阅读了文档,但我可能高估了 useCallback
    猜你喜欢
    • 2021-12-04
    • 2019-05-25
    • 2019-01-25
    • 2019-11-30
    • 2012-10-30
    • 2011-01-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多