首页 > 解决方案 > 反应小部件中的无效挂钩调用

问题描述

我正在尝试在 React 中创建一个小部件,它可以用作基于 React 的项目中的 npm 包,也可以将它添加到 Vanilla Javascript 的脚本标签中。

我面临的问题是当我在我的小部件中使用钩子时,我收到无效的钩子调用错误,因为它有多个 React 副本,一个在小部件中,另一个是消费者项目。

我试过什么?

  1. 避免在小部件中调用钩子它已经解决了这个问题,但是如果第三方库组件使用钩子,问题就会再次出现。
  2. 在对等依赖项中添加了 react 和 react-dom 但是我不能在 vanilla 项目中使用这个小部件。

这是 webpack.config

const HtmlWebPackPlugin = require("html-webpack-plugin");
const increaseSpecificity = require("postcss-increase-specificity");
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const path = require('path');

const htmlPlugin = new HtmlWebPackPlugin({
    template: "./src/index.html",
    filename: "./index.html"
});

// const bundleAnalyzerPlugin = new BundleAnalyzerPlugin();

module.exports = {
    entry: path.join(__dirname, 'src/index.ts'),
    output: {
        path: path.join(__dirname, 'dist'),
        filename: 'app-launcher.js',
        library: 'AppLauncher',
        libraryTarget: 'umd'
    },
    resolve: {
        extensions: ["*", ".tsx", ".ts", ".js", ".jsx"],
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: {
                    loader: "babel-loader"
                }
            },
            {
                test: /\.(ts|tsx)?$/,
                use: "ts-loader",
                exclude: /node_modules/
            },
            {
                test: /\.(scss|css)$/,
                use: [
                    "style-loader", "css-loader", "cssimportant-loader",
                    {
                        loader: "postcss-loader",
                        options: {
                            postcssOptions: {
                                plugins: [
                                    increaseSpecificity({
                                        stackableRoot: ".cleanslate",
                                        repeat: 1
                                    })
                                ],
                            },
                            sourceMap: false
                        }
                    }
                ]
            },
            {
                test: /\.svg$/,
                use: ["babel-loader", "svg-inline-loader?classPrefix"]
            },
        ]
    },
    plugins: [htmlPlugin],
    // plugins: [htmlPlugin, bundleAnalyzerPlugin],
    optimization: {
        minimize: true
    }
};

和 package.json

{
  "name": "app-launcher",
  "version": "1.0.0",
  "description": "",
  "scripts": {
    "start": "webpack serve --mode development --open",
    "build": "webpack --mode production"
  },
  "main": "dist/app-launcher.js",
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@babel/core": "^7.14.6",
    "@babel/preset-env": "^7.14.5",
    "@babel/preset-react": "^7.14.5",
    "@types/react": "^17.0.11",
    "@types/react-dom": "^17.0.8",
    "babel-loader": "^8.2.2",
    "css-loader": "^5.2.6",
    "cssimportant-loader": "^0.4.0",
    "html-webpack-plugin": "^5.3.1",
    "postcss-increase-specificity": "^0.6.0",
    "postcss-loader": "^6.1.0",
    "style-loader": "^2.0.0",
    "svg-inline-loader": "^0.8.2",
    "ts-loader": "^9.2.3",
    "typescript": "^4.3.4",
    "webpack": "^5.39.1",
    "webpack-bundle-analyzer": "^4.4.2",
    "webpack-cli": "^4.7.2",
    "webpack-dev-server": "^3.11.2"
  },
  "dependencies": {
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-inlinesvg": "^2.3.0"
  }
}

解决方案

在 webpack 配置中添加了外部组件,例如

        externals: {
            "react": "React",
            "react-dom": "ReactDOM"
        }

为了在纯 JS 中使用我的包,我使用了 React 和 ReactDOM CDN。

<script crossorigin src="https://unpkg.com/react@17/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script>

我仍然愿意接受其他建议。

标签: javascriptreactjswebpackreact-hooks

解决方案


推荐阅读