动态导入反应挂钩

时间:2020-06-10 08:09:34

标签: javascript reactjs react-hooks dynamic-import

我们可以基于传递给组件的值动态导入钩子吗?

例如。

App.js

<BaseComponent isActive />

BaseComponent.js

if(props.isActive) {
  // import useActive (custom Hook)
}

即使道具包含假值,我也不希望导入这些(自定义钩子)文件并增加BaseComponent的大小。

2 个答案:

答案 0 :(得分:1)

您可以dynamically import钩子,因为它只是一个函数(使用require),但是您不应该,因为您不能在条件内部使用钩子

请参见Rules of Hooks

仅在顶层呼叫挂钩不要在循环,条件或嵌套函数中调用挂钩。

如果要有条件地使用钩子,请使用其实现look for example at skip option of useQuery hook from Apollo GraphQL Client)中的条件。

const useActive = (isUsed) => {
  if (isUsed) {
    // logic
  }
}

答案 1 :(得分:-1)

您应该提取useActive钩子中的逻辑并动态导入它,而不是动态导入该钩子,因为您不应该在循环,条件或嵌套函数中调用钩子Rules of Hooks

假设您的useActive钩子试图更新文档标题(在现实世界中,您必须考虑使用动态导入的一大段代码)

它可以通过以下方式实现:

// useActive.js

import { useEffect } from "react";    
export function useActive() {
  useEffect(() => {
    document.title = "(Active) Hello World!";
  }, []);
}

您尝试在BaseComponent中使用它:

// BaseComponent.js

function BaseComponent({ isActive }) {
  if (isActive) { // <-- call Hooks inside conditions ❌
    import("./useActive").then(({ useActive }) => {
      useActive();
    });
  }
  return <p>Base</p>;
}

在这里您违反了“请勿在条件内调用Hooks”规则,并且会出现Invalid hook call.错误。

因此,除了动态导入钩子之外,您还可以提取钩子内部的逻辑并动态导入它:

// updateTitle.js

export function updateTitle() {
  document.title = "(Active) Hello World!"
}

然后在挂钩中进行isActive检查:

// BaseComponent.js

function BaseComponent({ isActive }) {
  useEffect(() => {
    if (!isActive) return;

    import("./updateTitle").then(({ updateTitle }) => {
      updateTitle();
    });
  }, [isActive]);

  return <p>Base</p>;
}

它在不违反任何钩子规则的情况下正常工作。

我已附上CodeSandbox,供您试用:

Edit hardcore-wing-p3uvc