如何在我的组件库中使用 React 钩子?

Posted

技术标签:

【中文标题】如何在我的组件库中使用 React 钩子?【英文标题】:How do I use React hooks in my component library? 【发布时间】:2020-02-11 10:45:53 【问题描述】:

我目前正在通过 NPM 链接创建一个包含在 Nextjs 项目中的组件库,并且很难让它始终如一地加载而不会出现错误。最新的是

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

这是一个 Typescript 组件,但据我所知,我所做的还可以,但它不是在玩运动。代码如下:

        import React,  useEffect  from "react";
        import  FlagIcon  from "react-flag-kit";

        const LanguageSwitcher = () => 
            useEffect(() => 
                alert('Yo!');
            )
            return (
                <div className="w-full justify-end">
                    <button>
                        <div className="flex items-center">
                            <FlagIcon code="GB" /> <span className="block ml-2">English</span>
                        </div>
                    </button>
                </div>
            )
        

        export default LanguageSwitcher

然后将其导入库中的另一个组件,然后导入 Nextjs 页面。这是错误出现的地方。

我不确定这是 webpack 还是 typescript 编译问题,尝试了我能想到的所有不同目标,尝试谷歌搜索各种东西,但似乎与我的情况无关。它甚至可能不是 React 问题,而是 Typescript 和 Webpack 的问题,但我对这些的接触是非常新的。

我的 webpack 配置:

        var path = require('path');
        module.exports = 
          entry: './src/index.ts',
          devtool: "source-map",
          output: 
            path: path.resolve(__dirname, 'build'),
            filename: 'index.js',
            libraryTarget: 'commonjs2'
          ,
          module: 
            rules: [
              
                test: /\.ts(x?)$/,
                use: 'ts-loader',
                exclude: /node_modules/,
              ,
              
                enforce: "pre",
                test: /\.js$/,
                loader: "source-map-loader"
              
            ]
          ,
          resolve: 
            extensions: [ '.tsx', '.ts', '.js' ],
          
        ;

我的tsconfig.json


    
      "compilerOptions": 
        "outDir": "build",
        "module": "esnext",
        "target": "es6",
        "lib": ["es6", "dom", "es2016", "es2017"],
        "sourceMap": true,
        "allowJs": false,
        "jsx": "react",
        "declaration": true,
        "moduleResolution": "node",
        "forceConsistentCasingInFileNames": true,
        "noImplicitReturns": true,
        "noImplicitThis": true,
        "noImplicitAny": true,
        "strictNullChecks": true,
        "suppressImplicitAnyIndexErrors": true,
        "noUnusedLocals": true,
        "noUnusedParameters": true,
        "allowSyntheticDefaultImports": true
      ,
      "include": ["src"],
      "exclude": ["node_modules", "build"]
    

任何指点或帮助将不胜感激!

我还尝试将所有内容恢复为原版 JS,但问题仍然存在,所以我认为这可能与 webpack 有关?

编辑

这是我的完整 package.json 文件以及 Nextjs 所拥有的


  "name": "some/package",
  "version": "1.0.0",
  "description": "",
  "main": "build/index.js",
  "scripts": 
    "test": "jest",
    "start": "webpack --watch --mode=development",
    "build": "webpack"
  ,
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": 
    "react": "16.10.2",
    "webpack": "^4.41.1"
  ,
  "devDependencies": 
    // ...
    "@types/react": "^16.9.5",
    "@types/react-dom": "^16.9.1",
    "react": "16.10.2",
    "react-dom": "^16.10.2",
    "ts-loader": "^6.2.0",
    "typescript": "^3.6.4",
    "webpack-cli": "^3.3.9"
  

    "react": "16.10.2",
    "react-dom": "16.10.2"

【问题讨论】:

它不是打字稿或 webpack,它的反应是在谈论错误的钩子用法 您在使用reactreact-dom 的哪些版本? 目前在 Next 和库中使用 16.10.2 也许这可以帮助***.com/questions/58365151/… 感谢您的链接,虽然这是在 Mac 上,所以我认为它不适用:/ 【参考方案1】:

原来这是由于组件库中的符号链接反应问题

https://reactjs.org/warnings/invalid-hook-call-warning.html#duplicate-react

通过运行链接中的步骤修复:

npm link ../myapp/node_modules/react // Run within the component library

【讨论】:

这解决了我的问题!谢谢!【参考方案2】:

面临同样的问题。但是,组件库不归我所有,因此不得不使用这个dependency resolution by 'Yarn'

这是我最初的依赖树

project
|- componentLibrary
|  |- react@16.10
|  |- react-dom@16.10
|- react@17.0.1
|- react-dom@17.0.1

在我的 package.json 中添加了以下 sn-p

"resolutions": 
  "componentLibrary/react": "17.0.1",
  "componentLibrary/react-dom": "17.0.1"
,

这解决了我对项目的 reactreact-dom 的依赖关系。

【讨论】:

以上是关于如何在我的组件库中使用 React 钩子?的主要内容,如果未能解决你的问题,请参考以下文章

如何防止我的功能组件使用 React 备忘录或 React 钩子重新渲染?

React 生命周期钩子

如何使用 JEST、Enzyme 在 React 中测试自定义钩子?

在 React 中,如何在所有组件中拥有一个自定义钩子实例?

如何使用钩子将项目附加到 React 组件中的数组?

如何在 React 中使用钩子预初始化状态?