Search code examples
reactjsnpmwebpacknpm-package

Problem with "TypeError: Cannot read property 'useState' of null" in React Library - Create NPM Package


I want to create a local npm package containing some React components called myscript-package.

./package.json
{
  "name": "pack-script",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@babel/plugin-proposal-unicode-property-regex": "^7.18.6",
    "@fortawesome/free-solid-svg-icons": "^6.5.2",
    "@fortawesome/react-fontawesome": "^0.2.0",
    "react-scripts": "5.0.1",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "web-vitals": "^2.1.4"
  },
  "scripts": {
    "build": "microbundle-crl --no-compress --format modern --css-modules false",
    "start": "microbundle-crl watch --no-compress --format es --css-modules false",
    "start:webpack": "npx webpack --config webpack.config.js",
    "start:tailwind": "npx tailwindcss -i ./src/tailwind.css -o ./output.css --watch",
    "build:react": "GENERATE_SOURCEMAP=false react-scripts build"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "autoprefixer": "^9.8.8",
    "microbundle-crl": "^0.13.11",
    "microbundle-crl-with-assets": "^0.13.12",
    "postcss": "8.4.31",
    "postcss-loader": "^8.1.1",
    "prettier": "3.2.5",
    "tailwindcss": "^3.3.4",
    "webpack-cli": "^5.1.4"
  },
  "peerDependencies": {
    "react": "^16 || ^17 || ^18",
    "react-dom": "^16 || ^17 || ^18"
  }
}
./index.js
import './output.css';
export * from './dist/myscript-package.esm';
./src/index.js
export { WidgetMini } from './WidgetMini';
export { Widgets } from './Widgets';

When I install it with npm i project-directory/myscript-package and import it into a new project like this:

import {WidgetMini} from "pack-script";

//...
return (
  <WidgetMini offer={offer} />
);
//...

I encounter this error:

Uncaught TypeError: Cannot read properties of null (reading 'useState') at useState (react.development.js:1622:1) at WidgetMini (WidgetMini.jsx:15:43) at renderWithHooks (react-dom.development.js:15486:1) at mountIndeterminateComponent (react-dom.development.js:20103:1) at beginWork (react-dom.development.js:21626:1) at beginWork$1 (react-dom.development.js:27465:1) at performUnitOfWork (react-dom.development.js:26596:1) at workLoopSync (react-dom.development.js:26505:1) at renderRootSync (react-dom.development.js:26473:1) at recoverFromConcurrentError (react-dom.development.js:25889:1)

Additional info:

  • used-in-project/webpack.common.js
const HtmlWebpackPlugin = require("html-webpack-plugin");
// const CopyPlugin = require("copy-webpack-plugin");
const path = require("path");

module.exports = {
    mode: "development",
    devtool: "cheap-module-source-map",
    entry: {
        index: "./src/index.js",
    },
    module: {
        rules: [
            {
                test: /\.(png|jpe?g|gif|svg)$/i,
                use: [
                    {
                        loader: "file-loader",
                    },
                ],
            },
            {
                test: /\.?(js|jsx)$/,
                exclude: /node_modules/,
                use: {
                    loader: "babel-loader",
                },
            },
            {
                test: /\.css$/i,
                // include: path.resolve(__dirname, 'src'),
                use: ['style-loader', 'css-loader', 'postcss-loader'],
            },
        ],
    },
    resolve: {
        extensions: [".js", ".jsx", ".json"],
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: "./src/index.html",
            filename: "index.html",
        }),
    ],
};

I created a component without useState or useEffect, and it functioned correctly. These components worked in Vite (React template), but they are not functioning in npx-create-react.


Solution

  • It seems you have implemented the logic inside your UI library. It creates conflict to handle the main state manager. To solve this issue, you should separate views and functionality from each other. So, remove useState from your library and pass props to its components instead.