【问题标题】:Invalid hook call on npm-link librarynpm-link 库上的无效挂钩调用
【发布时间】:2021-01-24 18:10:54
【问题描述】:

问题描述:

  • 我目前正在创作一个名为eformless的包

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

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

    // inside my 'sandbox' App.tsx
    import React from 'react'
    import { useField } from 'eformless'
    
    const App = () => {
      const [test, handleChange] = useField('testing')
      return (
        <input type="text" value={test.value} onChange={handleChange} />
      )
    }
    

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

  1. 您可能有不匹配的 React 版本和渲染器(例如 React DOM)
  2. 您可能违反了 Hooks 规则
  3. 您可能在同一个应用程序中拥有多个 React 副本 有关如何调试和修复此问题的提示,请参阅 altered link due to stackoverflow ToS

问题发生的地方:

问题似乎指向我的库,我在其中编写了一个自定义挂钩,该挂钩使用从 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 ^
}

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

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

我尝试了什么:

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

当您使用 npm link 或等效项时,也会出现此问题。在这种情况下,你的打包器可能会“看到”两个 React——一个在应用程序文件夹中,一个在你的库文件夹中。假设 myapp 和 mylib 是同级文件夹,一种可能的解决方法是从 mylib 运行 npm link ../myapp/node_modules/react。这应该使库使用应用程序的 React 副本。

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

无论哪种方式,我都觉得很困惑,因为 runnign npm ls react 只显示一个版本的 react 并且它应该是有效的,因为 useState 是在自定义钩子中使用的顶级。

重现问题

两个仓库都是公开的

【问题讨论】:

    标签: node.js reactjs typescript npm npm-link


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

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

    相反,将 react 移至无格式 package.json 中的对等依赖项,删除您的 node_modules 目录并运行 npm install

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

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

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

    【讨论】:

    • 是的,我真的很惊讶它是如何到达那里的,因为它应该在我的.gitignore 中。至于devDependencies -&gt; peerDependencies,我想你可能是对的。忘记了,等一下。
    • 是的,这确实解决了问题,我将添加一个小细节,我更改了 peerDeps 以反映带有钩子的最低要求版本为"react": "&gt;=16.8"
    • ? 我不确定这是一个合适的解决方案。我有同样的问题,但我的开发依赖项中有 React 是有原因的——运行我的测试。如果我按照您的建议删除它并仅将 React 指定为对等依赖项,我的测试将失败。
    • 不管怎样,解决这个问题的方法是在 package.json 文件中添加分辨率配置,如下所述:github.com/facebook/react/issues/13991#issuecomment-449597362
    【解决方案2】:

    另一种选择是在依赖应用的构建中使用 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')
      }
    }
    

    【讨论】:

      【解决方案3】:

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

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

      图书馆中

      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 开发服务器,我不需要 node 命令。
      • 这也适用于我。虽然我无法完成第 6 步。
      猜你喜欢
      • 2021-07-03
      • 2022-10-04
      • 2021-09-08
      • 2020-08-13
      • 2021-12-07
      • 2020-08-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多