我正在为一个信用卡表单创建一个Reaction组件库,CreditCardForm.tsx如下所示:

加入时间:清华2007年01月25日下午3:33

import React, {useState} from "react";

interface CreditCardFormProps {
  testState: any;
  name: string;
  onChangeName: () => void;
  cardNumber: string;
  onChangeCardNumber: () => void;
  expirationDate: string;
  onChangeExpirationDate: () => void;
  cvv: string;
  onChangeCvv: () => void;
  onSubmit: () => void;
}


const CreditCardForm = (props: CreditCardFormProps) => {
  const [testState, setTestState] =useState<any>("hello")
  return (
    <form onSubmit={props.onSubmit}>
      <label htmlFor="name">Name on Card</label>
      <input
        type="text"
        id="name"
        name="name"
        value={props.name}
        onChange={props.onChangeName}
        required
        pattern="^[A-Za-z\s]*$"
        title="Please input your name correctly"
      />
      <p>test: {testState}</p>

      <label htmlFor="cardNumber">Card Number</label>
      <input
        type="text"
        id="cardNumber"
        name="cardNumber"
        value={props.cardNumber}
        onChange={props.onChangeCardNumber}
        required
        minLength={16}
        maxLength={16}
        pattern="^[0-9]*$"
        title="Your Card Number should contain only numbers."
      />
        <label htmlFor="expirationDate">Expiration Date</label>
        <input
          type="number"
          id="expirationDate"
          name="expirationDate"
          value={props.expirationDate}
          onChange={props.onChangeExpirationDate}
          required
          title="Please input your Expiration Date correctly"

        />

      <label htmlFor="cvv">CVV</label>
      <input
        type="text"
        id="cvv"
        name="cvv"
        value={props.cvv}
        onChange={props.onChangeCvv}
        required
        minLength={3}
        maxLength={3}
        title="Your CVV should contain only numbers."

      />

      <button type="submit">Submit</button>
    </form>
  );
};

export default CreditCardForm;

Package.json

{
  "name": "@packagename",
  "version": "0.1.24",
  "description": "A react component library",
  "scripts": {
    "rollup": "rollup -c"
  },
  "author": " Name ",
  "license": "ISC",
  "peerDependencies": {
    "react-dom": "^18.2.0",
    "react": "^18.0.2"
  },
  "devDependencies": {
    "@rollup/plugin-commonjs": "^24.1.0",
    "@rollup/plugin-node-resolve": "^15.0.2",
    "@rollup/plugin-typescript": "^11.1.0",
    "@types/react": "^18.2.0",
    "rollup": "^3.21.0",
    "rollup-plugin-dts": "^5.3.0",
    "source-map-explorer": "^2.5.3",
    "tslib": "^2.5.0",
    "typescript": "^5.0.4"
  },
  "main": "dist/cjs/index.js",
  "module": "dist/esm/index.js",
  "files": [
    "dist"
  ],
  "types": "dist/index.d.ts",
  "publishConfig": {
    "registry": "https://npm.pkg.github.com/@username"
  },
  "dependencies": {
    "react": "^18.0.2",
    "react-dom": "^18.2.0"

  }
}

我使用ROLLUP来构建我的包,我的ROLUP.config.mjs文件如下所示:

import resolve from "@rollup/plugin-node-resolve";
import commonjs from "@rollup/plugin-commonjs";
import typescript from "@rollup/plugin-typescript";
import dts from "rollup-plugin-dts";
import packageJson from "./Package.json" assert { type: "json" }; //we import Package.json so when we use commonjs modules

export default [
  //first configuration object
  {
    input: "src/index.ts", //entry point for this part of our library (it exports all of our components so that the user can import the library)
    output: [
      {
        file: packageJson.main,
        format: "cjs",
        sourcemap: true,
      }, //commonjs modules, which will use the main field of packageJson module
      {
        file: packageJson.module,
        format: "esm",
        sourcemap: true,
      }, //for the es6 modules
    ],
    plugins: [
      resolve(),
      commonjs(),
      typescript({ tsconfig: "./tsconfig.json" }),
    ], //node resolve plugin, and the other plugins (typescript plugin needs the specific directory)
  },

  //second configuration object
  {
    input: "dist/esm/types/index.d.ts",
    output: [{ file: "dist/index.d.ts", format: "esm" }],
    plugins: [dts()],
  },
];

因此,当我发布此Reaction库(NPM PUBLISH),并将其安装在Reaction应用程序项目(以测试它)上,然后运行该项目(NPM Start)时,它会返回以下错误:

Compiled with problems:
×
ERROR
Cannot read properties of null (reading 'useState')
TypeError: Cannot read properties of null (reading 'useState')
    at Object.useState (http://localhost:3000/static/js/bundle.js:2135:29)
    at CreditCardForm (http://localhost:3000/static/js/bundle.js:3112:50)
    at renderWithHooks (http://localhost:3000/static/js/bundle.js:24102:22)
    at mountIndeterminateComponent (http://localhost:3000/static/js/bundle.js:27388:17)
    at beginWork (http://localhost:3000/static/js/bundle.js:28684:20)
    at HTMLUnknownElement.callCallback (http://localhost:3000/static/js/bundle.js:13694:18)
    at Object.invokeGuardedCallbackDev (http://localhost:3000/static/js/bundle.js:13738:20)
    at invokeGuardedCallback (http://localhost:3000/static/js/bundle.js:13795:35)
    at beginWork$1 (http://localhost:3000/static/js/bundle.js:33669:11)
    at performUnitOfWork (http://localhost:3000/static/js/bundle.js:32916:16)

为什么会显示这一点,我如何修复它?

推荐答案

正如我们在注释中所讨论的,当您构建一个应该使用宿主的运行时的库时,在您的例子中是reactreact-dom,您必须将它们外部化.

基本上,你应该做两件事:

  1. package manager知道您不想让lib的客户端再次下载react .在lib的Package.json中,您需要从dependencies中删除reactreact-dom,并将它们放入devDependenciespeerDependencies中.devDependencies表示您使用REACT进行本地开发,peerDependencies表示用于生产,REACT将由宿主应用程序提供.
  2. 然而,这还不够,你还必须明确地告诉Rollup,它应该是externalize react deps.原因很简单-当Rollup判断您的源文件时,它会解析它找到的import条语句,并且它主要通过查看node_modules来实现这一点.在你的例子中,不管你是在dependencies还是devDependecies中定义了REACTION,它只会在node_modules中找到REACTIVE数据并把它们Bundle 到你的库中.

你违反了2nd的条件,你的应用程序最终得到了2 sets of react dependencies,这会抛出你的错误.

现在您的错误令人困惑,因为它听起来像是错误地解决了Reaction导入,但实际上最初的错误是You might have more than one copy of React in the same app(我试图亲自运行您的库).

根本原因就这么多了,现在怎么fix point 2呢?只需配置汇总以外部化react !

rollup.config.mjs

import external from 'rollup-plugin-peer-deps-external';

export default [
  {
    plugins: [
      external(),
      // your other plugins
    ],
    external: ["react", "react-dom"],
    // rest of your config
  }
];

这样,您就可以告诉Rollup,当它遇到它们的导入时,它不应该Bundle reactreact-dom,而是准备让主机应用程序拥有它们.这将从您的库Bundle 包中删除REACTIVE DELP,并消除您的错误!

Reactjs相关问答推荐

sourceBuffer. appendBuffer成功,但h5视频播放器卡住了

在带有和设计的表格中禁用和取消选中复选框

有没有办法将MUI网格元素与Flex-Start对齐?

当列表中的项的顺序改变并且使用唯一键作为它们的索引时,Reaction如何看待呈现方面?

获取未捕获的错误:Gatsby生产版本上的最小化react 错误#418

在动态React组件中删除事件侦听器

Reaction路由DOM v6不包含上下文(Supabase)

关于forwardRef,我可以';我不理解第二个用例

useEffect firebase 清理功能如何工作?

太多的重新渲染 - React 中的无限循环.如何使用React.effect并使用fetch?

找不到名称setCometChat

console.logs 没有显示在浏览器控制台上,但显示在我的终端上

Mui 在 TextField 标签上添加工具提示显示两个工具提示框

React中的功能性组件克隆优化

页面不显示

NextJS htaccess 设置

Reactjs 表单未反映提交时的更改

如何将 id 从页面传递到另一个页面?

当页面重新加载react 路由导航到第一页 v6

根据计算 ReactJs 更新输入字段