【问题标题】:Invalid hook call on npm link a library to applicationnpm 上的无效挂钩调用将库链接到应用程序
【发布时间】:2021-07-03 23:29:53
【问题描述】:

挂钩调用无效。 Hooks 只能在函数组件的主体内部调用。这可能由于以下原因之一而发生: 1. React 和渲染器的版本可能不匹配(例如 React DOM) 2. 你可能违反了 Hooks 规则 3. 你可能在同一个应用中拥有多个 React 副本。

我正在开发自己的组件库,并通过npm 链接在我的应用程序中使用相同的库,但在测试时出现上述错误。

这是我的 webpack.config

const path = require('path');

module.exports = {
    entry: './src/index.ts',
    devtool: 'eval-source-map',
    module: {
        rules: [
            {
                // "oneOf" will traverse all following loaders until one will
                // match the requirements. When no loader matches it will fall
                // back to the "file" loader at the end of the loader list.
                oneOf: [
                    {
                        test: /\.(tsx|ts|mjs)$/,
                        exclude: /node_modules/,
                        use: {
                            loader: 'babel-loader',
                            options: {
                                plugins: [['@babel/plugin-proposal-class-properties'], ['@babel/plugin-transform-runtime', { "regenerator": true }]],
                                presets: ['@babel/preset-env', '@babel/preset-react', '@babel/preset-typescript'],
                            },
                        },
                    },
                    
                    {
                        test: /\.mjs$/,
                        use: {
                            loader: 'babel-loader',
                            options: {
                                presets: ['@babel/preset-env'],
                            },
                        },
                    },
                    {
                        test: /\.(css|scss)$/,
                        use: [{ loader: 'style-loader' }, { loader: 'css-loader' }, { loader: 'sass-loader' }],
                    },
                    // "url" loader works like "file" loader except that it embeds assets
                    // smaller than specified limit in bytes as data URLs to avoid requests.
                    // A missing `test` is equivalent to a match.
                    {
                        exclude: [/\.js$/, /\.ts$/, /\.html$/, /\.json$/],
                        loader: require.resolve('url-loader'),
                        options: {
                            limit: 10000,
                            name: 'static/media/[name].[hash:8].[ext]',
                        },
                    },
                ],
            },
        ],
    },
    resolve: {
        extensions: ['.mjs', '.js', '.ts', '.tsx', '.json'],
    },
    output: {
        path: path.resolve(__dirname, 'dist/'),
        publicPath: '',
        filename: 'bundle.js',
        libraryTarget: 'commonjs'
    }
};

这是我的 package.json

{
  "name": "abc",
  "version": "1.0.42",
  "description": "A React component library",
  "main": "dist/bundle.js",
  "types": "dist/types/index.d.ts",
  "scripts": {
    "test": "jest",
    "build:development": "npm-run-all --parallel webpack:watch generate-typings",
    "build:production": "npm-run-all webpack:prod generate-typings",
    "build:clean": "rmdir /Q /S dist",
    "generate-typings": "tsc --declaration --emitDeclarationOnly",
    "styleguide": "npx styleguidist server",
    "styleguide:build": "npx styleguidist build",
    "webpack:watch": "webpack --watch --mode=development",
    "webpack:prod": "webpack --mode=production",
    "localVersion": "node -p \"require('./package.json').version\"> localVersion.txt",
    "serverVersion": "npm view @company/abc version > serverVersion.txt"
  },
  "repository": {
    "type": "git",
    "url": "url"
  },
  "keywords": [
    "react",
    "components",
    "typescript"
  ],
  "author": "Spencer Cousino",
  "license": "ISC",
  "devDependencies": {
    "@babel/core": "^7.11.1",
    "@babel/plugin-proposal-class-properties": "^7.10.4",
    "@babel/preset-env": "^7.11.0",
    "@babel/preset-react": "^7.10.4",
    "@babel/preset-typescript": "^7.10.4",
    "@fortawesome/fontawesome-svg-core": "^1.2.28",
    "@fortawesome/free-solid-svg-icons": "^5.13.0",
    "@types/enzyme": "^3.10.5",
    "@types/fetch-mock": "^7.3.2",
    "@types/jest": "^24.9.1",
    "@types/nock": "^10.0.3",
    "@types/node": "^11.15.9",
    "@types/react": "^16.9.0",
    "@types/react-dom": "^16.9.0",
    "@types/react-table": "^6.8.7",
    "async-wait-until": "^1.2.4",
    "babel-loader": "^8.1.0",
    "css-loader": "^1.0.1",
    "enzyme": "^3.11.0",
    "enzyme-adapter-react-16": "^1.15.2",
    "fetch-mock": "^7.7.3",
    "file-loader": "^3.0.1",
    "identity-obj-proxy": "^3.0.0",
    "jest": "^25.3.0",
    "nock": "^10.0.6",
    "node-fetch": "^2.6.1",
    "node-sass": "^4.14.1",
    "npm-run-all": "^4.1.5",
    "oidc-client": "^1.10.1",
    "powerbi-report-component": "^1.6.0",
    "prettier": "1.17.0",
    "react": "^16.14.0",
    "react-docgen-typescript": "^1.20.1",
    "react-dom": "^16.14.0",
    "react-router": "^5.1.2",
    "react-router-dom": "^5.1.2",
    "react-table": "6.10.3",
    "react-slick": "^0.23.2",
    "react-spinners": "^0.9.0",
    "react-styleguidist": "^11.1.5",
    "reactstrap": "^8.4.1",
    "sass-loader": "^7.3.1",
    "ts-jest": "^25.4.0",
    "typescript": "^3.8.3",
    "url-loader": "^1.1.2",
    "webpack": "^4.44.1",
    "webpack-cli": "^3.3.12"
  },
  "dependencies": {
    "@babel/plugin-transform-runtime": "^7.12.1",
    "@babel/runtime": "^7.12.5",
    "@company/abc": "0.0.6",
    "@company/abc1": "^1.2.0",
    "@company/abc2": "^1.0.23",
    "@company/abc3": "^1.9.1",
    "@company/abc4": "^1.0.1",
    "core-js": "^3.8.0",
    "date-fns": "^1.30.1",
    "react-bingmaps": "^3.6.1",
    "react-bootstrap": "^0.32.3",
    "react-grid-layout": "^0.16.6",
    "react-scripts": "^4.0.3",
    "react-tabs": "^3.1.1",
    "slick-carousel": "^1.8.1"
  },
  "peerDependencies": {
    "react": "~16.8.4",
    "react-dom": "~16.8.4",
    "@types/node": "^11.11.6",
    "node-fetch": "^2.3.0",
    "oidc-client": "^1.7.0",
    "powerbi-report-component": "^1.1.3",
    "@fortawesome/fontawesome-svg-core": "^1.2.17",
    "@fortawesome/free-solid-svg-icons": "^5.8.1",
    "react-slick": "^0.23.2",
    "react-spinners": "^0.5.3",
    "reactstrap": "^8.0.0"
  },
  "jest": {
    "transform": {
      "^.+\\.tsx?$": "ts-jest"
    },
    "setupFilesAfterEnv": [
      "./testSetup.ts"
    ],
    "moduleNameMapper": {
      "^.+\\.(css|scss)$": "identity-obj-proxy",
      "^.+\\.(svg)$": "<rootDir>/src/mocks/fileMock.js"
    },
    "moduleFileExtensions": [
      "js",
      "jsx",
      "ts",
      "tsx"
    ],
    "collectCoverageFrom": [
      "**/context-components/**/*.{js,jsx,ts,tsx}"
    ]
  }
}

我尝试了多种方法,但没有一个对我有用。 任何帮助将不胜感激。

【问题讨论】:

  • 可以分享一下出错的代码吗?
  • {}} title="Title" >
    {( "警告")}
    获取来自库之一的此组件的错误。
  • 我没有在我的库中使用任何钩子。实际上使用类组件而不是功能组件。但是我在开发我的库时引用的另一个库中使用了钩子。
  • 那是你的问题。所有的 javascript 都会被转译,所以你应该使用支持你的 React 版本的包,或者升级你的 React 版本

标签: reactjs npm webpack


【解决方案1】:

Hooks 可以在 react 组件中调用,也可以在自定义 hook 中调用。如果任何函数返回一些 jsx,则它是一个反应组件。
对于hooksreact 中有一些规则。 Rules about react hooks.
如果你想了解自定义钩子,那么 read about custom hooks here.

【讨论】:

    猜你喜欢
    • 2021-01-24
    • 2020-01-06
    • 1970-01-01
    • 1970-01-01
    • 2022-10-04
    • 2021-09-08
    • 1970-01-01
    • 1970-01-01
    • 2020-11-29
    相关资源
    最近更新 更多