npm-link 库上的挂钩调用无效

Invalid hook call on npm-link library

问题描述:

Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:

  1. You might have mismatching versions of React and the renderer (such as React DOM)
  2. You might be breaking the Rules of Hooks
  3. You might have more than one copy of React in the same app See altered link due to Whosebug ToS for tips about how to debug and fix this problem.

出现问题的地方:

问题似乎指向我的库,我在其中编写了一个使用从 React 导入的挂钩的自定义挂钩。
这是我的代码中有问题的摘录:

export const useField = <T>(
  input: T
  ...checkFunctions: Array<(...args: unknown[]) => unknown>
): [FieldType<T>, FieldHandlerFunction<T>, FieldHandlerFunction<T>] => {
  const [value, setValue] = useState(input)
  const [name, setName] = useState('')
  // Issue seems to be here ^
}

我的设置相当正常,似乎在其他项目中也能正常工作:

我尝试了什么:

我很自然地尝试通过错误消息中提供的 link 来解决问题。当 link 使用您自己的库时,这似乎是一个问题,如此处所述

This problem can also come up when you use npm link or an equivalent. In that case, your bundler might “see” two Reacts — one in application folder and one in your library folder. Assuming myapp and mylib are sibling folders, one possible fix is to run npm link ../myapp/node_modules/react from mylib. This should make the library use the application’s React copy.

我在我的 eformless 文件夹中做了 运行 npm link ../sandbox/node_modules/react,但这似乎没有帮助,即使在关闭节点服务器并重新编译之后也是如此。

无论哪种方式,我都觉得很困惑,因为 运行nign npm ls react 只显示了一个版本的 React,它应该是有效的,因为 useState 被使用了 top-自定义挂钩内的级别。

重现问题

两个存储库都是 public

  1. You might have more than one copy of React in the same app See altered link due to Whosebug ToS for tips about how to debug and fix this problem.

这是因为您在 devDependencies 中对 eformless 做出了反应。这会导致您的应用程序 运行 两个 React 实例。

相反,移动对 eformless package.json 中的对等依赖项做出反应,删除您的 node_modules 目录和 运行 npm install.

通过将 React 添加到对等依赖项,您是在通知模块打包器不要包含 React,而是期望依赖应用程序可以使用 React。

"peerDependencies": {
  "react": "^16.13.1"
}

此外,我注意到您已将 node_modules 目录签入 eformless。你不应该那样做。相反,将 node_modules 添加到您的 .gitignore 文件中。

以防万一它对其他人有用,我已经在我的库中使用 React 作为 'peer dependency',但仍然遇到这个问题。

我必须执行以下步骤来解决它:

在图书馆:

  1. 如果您还没有这样做,请将生成问题的库设置为 package.json 中的 peerDependencies 而不是 dependenciesdevDependencies,例如在我的例子中 react:
"peerDependencies": {
  "react": "^16.8.6",
  ...
}
  1. 运行 npm install
  2. 构建库(在我的例子中,使用 rollup -c npm 脚本)

在我的主应用程序中:

  1. 更改我的库的版本以指向我在 package.json 中具有相对路径的本地项目,例如
"dependencies": {
  "my-library": "file:../../libraries/my-library",
  ...
}
  1. resolve.symlinks = false 添加到我的主应用程序的 webpack 配置中

  2. --preserve-symlinks-main--preserve-symlinks 添加到我的 package.json 启动脚本中,例如:

"scripts": {
  "build": "set WEBPACK_CONFIG_FILE=all&& webpack",
  "start": "set WEBPACK_CONFIG_FILE=all&& webpack && node --preserve-symlinks-main --preserve-symlinks dist/server.js",
}
  1. 运行 npm install
  2. 运行 npm run start

另一种选择是在依赖应用程序的构建中使用 webpack alias 来删除 React 依赖项。

内部 webpack.config.js 应用程序使用链接依赖项:

resolve: {
  alias: {
    react: path.resolve(__dirname, '<app_path>/node_modules/react'),
    'react-dom': path.resolve(__dirname, '<app_path>/node_modules/react-dom')
  }
}

在您的主项目中使用别名。然后对于你的库,它将使用你的主项目的别名。

react : path.resolve(__dirname, './node_modules/react')