I am trying to break my code into separate packages to modularize my react application; doing so requires me to create react components in a separate the library that manages state using useState
.
However, when leveraging the library's component in the react app, I receive this error:
null is not an object (evaluating 'dispatcher.useState')
useState@http://localhost:3000/static/js/bundle.js:7493:24
Counter@http://localhost:3000/static/js/bundle.js:6017:65
renderWithHooks@http://localhost:3000/static/js/bundle.js:22612:31
mountIndeterminateComponent@http://localhost:3000/static/js/bundle.js:25896:32
Here is my setup:
React Library — package.json
{
"name": "lib-five",
"version": "1.0.0",
"description": "",
"main": "./dist/cjs/index.js",
"module": "./dist/esm/index.js",
"types": "./dist/esm/index.d.ts",
"scripts": {
"prepare": "npm run build",
"build": "yarn build:esm && yarn build:cjs",
"build:esm": "tsc",
"build:cjs": "tsc --module commonjs --outDir dist/cjs"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@types/react": "^18.2.48",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"typescript": "^5.3.3"
},
"peerDependencies": {
"react": ">=16"
},
"files": [
"dist"
]
}
Counter.tsx
import React, { useState } from 'react'
export const Counter: React.FC<{}> = () => {
const [count, setCount] = useState<number>(0)
const increment = () => setCount((c) => c + 1)
const decrement = () => setCount((c) => c - 1)
return (
<div>
<h1>Counter</h1>
<p>Count: { count }</p>
<button onClick={ increment}>Increment</button>
<button onClick={ decrement }>Decrement</button>
</div>
)
}
index.ts
import { Counter } from './Counter'
export { Counter }
React App (using the library) — package.json
{
"name": "uselibtest",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"@types/jest": "^27.5.2",
"@types/node": "^16.18.68",
"@types/react": "^18.2.47",
"@types/react-dom": "^18.2.18",
"lib-five": "file:../lib-five",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"typescript": "^4.9.5",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"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"
]
}
}
App.tsx
import React
import { Counter } from 'lib-five'
function App() {
return (
<div style={ containerStyle }>
<Counter />
</div>
)
}
export default App