【问题标题】:Does this "custom react hook" breaks the hooks law?这个“自定义反应钩子”是否违反了钩子法?
【发布时间】:2021-05-17 03:30:36
【问题描述】:

我在 useEffects 中以相同的格式语法使用了许多 useCallbacks,并且想缩短它们。所以,我将它们映射到这个钩子中。 effects 是一个 useCallback 函数数组。

import React from 'react';
    const useEffects = (effects: Function[]) =>
      effects.map((effect) =>
        React.useEffect(() => {
          effect();
        }, [effect])
      );
export default useEffects;

【问题讨论】:

  • 是的,你不能在回调中useEffect
  • React hooks 应该在组件的最顶层调用,请查看reactjs.org/docs/…
  • 我相信你不能在数组中使用钩子。因为我们不知道数组的长度。所有的钩子都是根据它们的物理位置顺序注册的。

标签: reactjs react-tsx


【解决方案1】:

钩子不能在数组中定义。

我最近写了一篇关于 hooks 的渲染顺序的文章。 https://windmaomao.medium.com/understanding-hooks-part-4-hook-c7a8c7185f4e

Hooks 是如何定义的。

function hook(Hook, ...args) {
  let id = notify()
  let hook = hooks.get(id)
  if(!hook) {
    hook = new Hook(id, element, ...args)
    hooks.set(id, hook)
  }
  return hook.update(...args)
}

当一个钩子被注册时,它需要一个唯一的 id,如notify() 行。这只是一个简单的i++ 放置在其中写入挂钩的组件内。

所以如果你有一个固定的钩子物理位置,你就有一个固定的id。否则id 可以是随机的,并且由于每个渲染周期都会调用渲染Component 函数,因此随机的id 不会在下一个渲染周期中找到正确的钩子。

这就是为什么if也不能写在钩子语句之前的原因。试试看

  const Component = () => {
    const b = true
    if (!b) return null
    const [a] = useState(1)
  }

你应该得到类似的错误。

【讨论】:

    猜你喜欢
    • 2019-06-15
    • 1970-01-01
    • 2021-09-29
    • 2022-07-18
    • 2020-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-03
    相关资源
    最近更新 更多