自定义钩子返回 Promise 但在 useEffect 内部解析

Jon*_*ink 3 reactjs es6-promise react-hooks

我正在尝试编写一个钩子,它执行动态import并返回一个Promise在导入完成时解析的钩子。

这是我设想的用法:

await useAfterImport("@custom/path");
Run Code Online (Sandbox Code Playgroud)

这是我的错误尝试:

const useAfterImport = (importPath:string) => {
  return new Promise<void>((resolve) => {
    useEffect(() => {
      import(importPath).then(() => {
        resolve();
      });
    }, [importPath]);
  });
};
Run Code Online (Sandbox Code Playgroud)

此尝试失败,因为违反了Hooks 规则:

React Hook“useEffect”无法在回调内调用。React Hooks 必须在 React 函数组件或自定义 React Hook 函数中调用。eslintreact-hooks/hooks 规则

有没有一种方法可以在不使用回调参数的情况下编写这样的钩子?我真的很希望能够返回一个Promise以便可以对其进行await编辑。

Cer*_*nce 11

我不认为 Promise 是正确的方法:

这是我设想的用法:

await useAfterCustomImport("@custom/path");
Run Code Online (Sandbox Code Playgroud)

React 组件函数体的顶层 - 唯一可以使用钩子的地方 - 不能在await它们内部 - 它们需要立即渲染一些东西(即使暂时是一个空片段)。

对于您想要做的事情,状态更有意义。您可以执行以下操作:

const useAfterCustomImport = (importPath: string) => {
  const [imported, setImported] = useState(false);
  useEffect(() => {
    import(importPath)
      .then(() => setImported(true))
      // .catch(handleErrors); // don't forget this part
  }, []);
  return imported;
};
Run Code Online (Sandbox Code Playgroud)

进而

const libImported = useAfterCustomImport('some-lib');
return !libImported ? null : (
  <div>
    // JSX that uses the library
  </div>
); 
Run Code Online (Sandbox Code Playgroud)

这遵循当前代码的当前逻辑,该逻辑似乎假设导入仅包含副作用,而不是解析为可用值。如果模块解析为可用值,则从imported自定义挂钩返回两者和解析值将是一个微不足道的调整。