Introduction
Let's consider the following versions as the current versions:
Let's consider the article that describes the same problem: Invalid Hook Call Warning – React.
Changes to get reproducible example
Client application (apptestone
)
Since the provided (posted right in the question, not on GitHub) source code of the client application is not complete, I have created an example client application with Create React App:
/question-72942020/src$ npx create-react-app apptestone
package.json
{
"name": "apptestone",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "5.16.4",
"@testing-library/react": "13.3.0",
"@testing-library/user-event": "13.5.0",
"libtestone": "file:../libtestone",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"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"
]
}
}
Resulting directory structure
/question-72942020/src$ tree --charset unicode -L 2
.
|-- apptestone
| |-- build
| |-- node_modules
| |-- package.json
| |-- package-lock.json
| |-- public
| |-- README.md
| `-- src
`-- libtestone
|-- dist
|-- node_modules
|-- package.json
|-- package-lock.json
`-- src
General changes
Library package (libtestone/package.json
): Reduce scope of dependencies
Update the file as follows:
"dependencies": {
},
<…>
"peerDependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
<…>
"devDependencies": {
"microbundle": "^0.15.0",
"@testing-library/jest-dom": "^5.16.4",
"@testing-library/react": "^13.3.0",
"@testing-library/user-event": "^13.5.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
},
Run the command:
/question-72942020/src/libtestone$ npm clean-install
Library component (libtestone/src/components/Dropdown.js
): Use «fallback» value
Update the function as follows:
const loadData = () => {
setDropdown(props.jsonData || ["Loaded data"]);
};
This will allow using the Dropdown
component like it is shown in your example:
function App() {
return (
<div>
<Dropdown />
</div>
);
}
Analysis
After making the changes described in the «Changes to get reproducible example» and «General changes» sections:
- The problem has been reproduced.
- The analysis has been started.
It is an important detail that you have installed the library package into the application package from a local file system (not from an npm registry).
It seems that had you installed the library from an npm registry, the changes described in the «General changes» section would be sufficient to solve the problem or would not be necessary at all.
It seems that the «Duplicate React» problem takes place according to the symptom (the output):
/question-72942020/src/apptestone$ npm ls react
[email protected] /question-72942020/src/apptestone
├─┬ @testing-library/[email protected]
│ └── [email protected] deduped
├─┬ [email protected] -> ./../libtestone
│ ├─┬ @testing-library/[email protected]
│ │ └── [email protected] deduped
│ ├─┬ [email protected]
│ │ └── [email protected] deduped
│ ├─┬ [email protected]
│ │ └── [email protected] deduped
│ └── [email protected] <!-- NOTE!
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
└── [email protected] <!-- NOTE!
Please, note the <!-- NOTE!
markers.
The article states:
This problem can also come up when you use npm link
or an equivalent. In that case, your bundler might “see” two Reacts — one in application folder and one in your library folder.
Possible solution
The article describes a possible solution:
Assuming myapp
and mylib
are sibling folders, one possible fix is to run npm link ../myapp/node_modules/react
from mylib
. This should make the library use the application’s React copy.
Let's adapt the solution to the current case.
The resulting command:
/question-72942020/src/libtestone$ npm link ../apptestone/node_modules/react ../apptestone/node_modules/react-dom
Please, note the working directory path (before $
).
Let's check the created symbolic links:
/question-72942020/src/libtestone$ ls -la node_modules/react{,-dom}
<…> node_modules/react -> ../../apptestone/node_modules/react
<…> node_modules/react-dom -> ../../apptestone/node_modules/react-dom
Let's check the duplication:
/question-72942020/src/apptestone$ npm ls react
[email protected] /question-72942020/src/apptestone
├─┬ @testing-library/[email protected]
│ └── [email protected] deduped
├─┬ [email protected] -> ./../libtestone
│ ├─┬ @testing-library/[email protected]
│ │ └── [email protected] deduped -> ./node_modules/react
│ ├─┬ [email protected]
│ │ └── [email protected] deduped -> ./node_modules/react
│ ├─┬ [email protected]
│ │ └── [email protected] deduped -> ./node_modules/react
│ └── [email protected] -> ./node_modules/react <!-- NOTE!
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
└── [email protected] <!-- NOTE!
Please, note the <!-- NOTE!
markers.
This is it.
Development workflow
Now it is possible to work on the library: make a change, build it (npm run build:lib
).
Given that the application is started in the development mode (npm start
), the library changes will be taken into account (upon library rebuild: npm run build:lib
).
Caveat
It seems that every time a package installation npm command (npm install
, etc.) is performed for the library project, the npm links will be reverted to module directories.
It is necessary to recreate them.
react
andreact-dom
aspeerDependencies
. – Oversidelibtestone
package into the client application package? For example, have you installed it from an npm registry (npm install libtestone
) or from a local file system (npm install path/to/libtestone
)? – Harwin--recursive
gives me two empty folders. – Spue