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

Raw*_*lus 17 node.js npm typescript reactjs npm-link

问题描述:

\n
    \n
  • 我目前正在编写一个名为eformless

    \n
  • \n
  • 我已经使用CRA创建了一个名为 的目录sandbox,我在其中链接了包。

    \n
  • \n
  • 当尝试使用我正在尝试测试的链接包启动沙箱反应应用程序时,我不断收到以下错误:

    \n
    // inside my \'sandbox\' App.tsx\nimport React from \'react\'\nimport { useField } from \'eformless\'\n\nconst App = () => {\n  const [test, handleChange] = useField(\'testing\')\n  return (\n    <input type="text" value={test.value} onChange={handleChange} />\n  )\n}\n
    Run Code Online (Sandbox Code Playgroud)\n
  • \n
\n
\n

错误:无效的挂钩调用。钩子只能在函数组件的主体内部调用。发生这种情况可能是由于以下原因之一:

\n
    \n
  1. 您的 React 和渲染器版本可能不匹配(例如 React DOM)
  2. \n
  3. 你可能违反了 Hooks 规则
  4. \n
  5. 您可能在同一应用中拥有多个 React 副本\n请参阅因 stackoverflow ToS 而更改的链接,了解有关如何调试和修复此问题的提示。
  6. \n
\n
\n

问题发生的地方:

\n

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

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

我的设置相当正常,并且在其他项目中似乎运行良好:

\n
    \n
  • 首先我通过捆绑我的库rollup -c
  • \n
  • eformless通过在我的库文件夹中创建了一个链接npm link
  • \n
  • sandbox并通过以下方式在我的文件夹中创建了符号链接npm link eformless
  • \n
\n

我尝试过的:

\n

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

\n
\n

当您使用 npm link 或等效项时,也会出现此问题。在这种情况下,您的捆绑程序可能会 \xe2\x80\x9csee\xe2\x80\x9d 两个 React \xe2\x80\x94,一个位于应用程序文件夹中,一个位于库文件夹中。假设 myapp 和 mylib 是同级文件夹,一种可能的修复方法是从 mylib 运行 npm link ../myapp/node_modules/react。这应该使库使用 application\xe2\x80\x99s React 副本。

\n
\n

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

\n

不管怎样,这对我来说似乎真的很困惑,因为 runnignnpm ls react只显示了单个版本的 React 并且它应该是有效的,因为useState在自定义钩子中使用了顶级。

\n

重现问题

\n

两个存储库都是公共的

\n\n

Ben*_*min 14

  1. 您可能在同一个应用程序中拥有多个 React 副本,请参阅由于 stackoverflow ToS 而更改的链接,了解有关如何调试和解决此问题的提示。

这是因为你的反应devDependencies是无形式的。这会导致您的应用程序运行两个 React 实例。

相反,将 React 移至 eformless 中的对等依赖项package.json,删除node_modules目录并运行npm install

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

"peerDependencies": {
  "react": "^16.13.1"
}
Run Code Online (Sandbox Code Playgroud)

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

  • 我不确定这是否是正确的解决方案。我有同样的问题,但我的开发依赖项中有 React 是有原因的——运行我的测试。如果我按照你的建议删除它并仅将 React 指定为对等依赖项,我的测试就会失败。 (7认同)

Ger*_*oza 7

为了防止它对其他人有用,我已经在我的库中使用 React 作为“对等依赖”,但仍然遇到这个问题。

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

在图书馆

  1. 如果您还没有这样做,请设置产生问题的库,而不是 或peerDependenciespackage.json例如在我的例子中:dependenciesdevDependenciesreact
"peerDependencies": {
  "react": "^16.8.6",
  ...
}
Run Code Online (Sandbox Code Playgroud)
  1. 跑步npm install
  2. 构建库(在我的例子中,使用rollup -cnpm 脚本)

在我的主应用程序中

  1. 更改我的库的版本以指向我的本地项目,其中包含相对路径package.json,例如
"dependencies": {
  "my-library": "file:../../libraries/my-library",
  ...
}
Run Code Online (Sandbox Code Playgroud)
  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",
}
Run Code Online (Sandbox Code Playgroud)
  1. 跑步npm install
  2. 跑步npm run start