Reputation: 281
I can't find where the culprit is. I tried to debug it, but can't found what really make it those error:
cannot read properties of null (reading 'useContext') && react.development.js:209 Warning: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
- You might have mismatching versions of React and the renderer (such as React DOM)
- You might be breaking the Rules of Hooks
- You might have more than one copy of React in the same app
App.js
function App() {
return (
<React.Fragment>
<Counter/>
</React.Fragment>
);
}
export default App;
index.js
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<Provider context={StoreContext} store={Store()}>
<App />
</Provider>
);
reportWebVitals();
CounterReducer.js
const CounterReducer = (state = { count: 0 } , action) => {
switch (action.type) {
case handleDencrement:
return state.count - 1
case handleIncrement:
return state.count + 1
default:
return state
}
}
export default CounterReducer;
context.js
const StoreContext = React.createContext();
export default StoreContext ;
Store.js
const Store = () => {
const store = useStore(CounterReducer);
return store
}
export default Store;
types.js
export const handleIncrement = 'handleIncrement' ;
export const handleDencrement = 'handleDencrement';
Counter.js
const Counter = () => {
const [count, setcount] = useState(0);
const handleIncrement = () => {
setcount(count + 1);
}
const handleDencrement = () => {
setcount(count - 1);
}
return (
<div>
<center>
<h1>Redux</h1>
<h1>{count}</h1>
<button className="btn btn-primary" onClick={handleIncrement}>Increment</button>
<button className="btn btn-warning" onClick={handleDencrement}>decrement</button>
</center>
</div>
);
}
export default Counter;
Upvotes: 28
Views: 176251
Reputation: 1
I had the same problem and discovered I made a silly mistake by calling one of my hooks outside of the function body. For instance, in AccountScreen component, I called dispatch outside the function body. Fixing this made the error go away
const dispatch = useAppDispatch();
export default function AccountScreen(){
return(
<View >
<Text>Account Screen</Text>
</View>
)
}
instead of
export default function AccountScreen(){
const dispatch = useAppDispatch();
return(
<View >
<Text>Account Screen</Text>
</View>)}
Upvotes: 0
Reputation: 261
Had the same problem in a monorepo project. After a long debugging I figured out that I was using a fixed version of react in my package.json
"react": "18.2.0",
"react-dom": "18.2.0",
And the version was conflicting with the version installed in the shared node_modules
. So to fix the problem, add the ^
before the version number to use any variant of your main react version 18.x.x
.
So the solution was this:
"react": "^18.2.0",
"react-dom": "^18.2.0",
Hope this helps someone !
Upvotes: 1
Reputation: 485
It can happen due to many reason but if you are creating your own library and testing it locally. use npm pack
avoid using npm link
npm link
not able to differentiate between version of react and this happened use npm pack
and then install the .tgz file
Upvotes: 3
Reputation: 633
My issue was upgrading to [email protected]
from [email protected]
. This is potentially due to having different react
versions for an Expo and Next.js app in a Turborepo. Be careful when bumping versions!
Upvotes: 0
Reputation: 31
I was getting the same error on 'next build' (wasted too many hours for solution)
SOLUTION: In my package.json I edited my build command under scripts
"build": "set NODE_ENV=production & next build",
Then in terminal instead of next build I executed
npm run build
Boom!! No error
Upvotes: 2
Reputation: 11
i had this problem and solved it by changing the version of react-bootstrap in package.json file.
delete all your node_modules, change the version like this:
"react-bootstrap": "2.9.2",
and after that, install your project again.
Upvotes: 0
Reputation: 41
For me, the problem was that one of my dependencies was using a different version (greater) of react
and react-dom
.
To force my dependencies to use the same version as my main package.json
file, i've used the resolutions
feature from yarn: https://classic.yarnpkg.com/lang/en/docs/selective-version-resolutions/
If you're using npm, take a look at https://docs.npmjs.com/cli/v9/configuring-npm/package-json#overrides
Upvotes: 3
Reputation: 31
I install one package outside of root folder. Then I removed the extra json file. Then I go to root folder by cd client command and install my package.then restart my project. worked!
Upvotes: 0
Reputation: 1
I have the same problem when I was using framer motion library the first time.
If you install any kind of library like npm install framer-motion
,
you should stay in your project directory, then the library should show up in on your
package.json
file.
That's the way you can get rid of the "can not read properties of null
".
Upvotes: 0
Reputation: 1
Try to uninstall node-packages. or
include change directory command before installing any package if you are using new terminal everytime.
so it creates only one node-modules,package-lock.json and package.json for the entire project.
like this:
npx create-react-app projectname
cd addtocart
npm start
cd projectname
npm install react-bootstrap bootstrap –save
cd projectname
npm install @reduxjs/toolkit
cd projectname
npm install react-redux
it worked for me.
Upvotes: 0
Reputation: 61
This might help someone, therefore adding to the answers. I had the same problem and it was the result of a silly mistake. While installing react bootstrap, I did npm install in the parent folder instead of project folder itself. When I later did npm install in the project folder itself the error was gone.
It was silly, for real.
Upvotes: 1
Reputation: 1
I had this problem and the answer was that I accidentally installed the locked package again, deleted it and it ran
Upvotes: 0
Reputation: 271
My issue was solved with Next.js by just stopping the server using 'Ctrl + C'. And restarted the server using 'npm run dev'. Hope this helps.
Upvotes: 21
Reputation: 17
Delete and Reinstall the npm modules , Using the command = npm install, you can install npm modules.
This will resolve the error.
Upvotes: -1
Reputation: 203323
Store
isn't a React component so it can't use the useStore
hook.
This hook returns a reference to the same Redux store that was passed in to the
<Provider>
component.
In other words, the useStore
hook is expecting a Redux Context to be provided to it from higher in the ReactTree.
From what I can tell of the code it seems you want the Store
function to create and return a Redux store object, to be passed to the Provider
component.
store.js
import { createStore, combineReducers } from 'redux';
import counter from '../path/to/counter.reducer';
const rootReducer = combineReducers({
counter,
});
const store = createStore(rootReducer);
export default store;
types
export const handleIncrement = 'handleIncrement' ;
export const handleDecrement = 'handleDecrement';
counter.reducer.js
The reducer function should maintain the state invariant. In this case the state is an object with a count
property.
const counterReducer = (state = { count: 0 }, action) => {
switch (action.type) {
case handleDecrement:
return {
...state,
count: state.count - 1
};
case handleIncrement:
return {
...state,
count: state.count + 1,
};
default:
return state;
}
};
index.js
...
import store from '../path/to/store';
...
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<Provider store={store}>
<App />
</Provider>
);
Counter
Instead of using local component state the component should use the useSelector
and useDispatch
hooks to read and update the counter
state in the store.
import { useDispatch, useSelector } from 'react-redux';
const Counter = () => {
const dispatch = useDispatch();
const count = useSelector(state => state.counter.count);
const handleIncrement = () => {
dispatch({ type: handleIncrement });
}
const handleDecrement = () => {
dispatch({ type: handleDecrement });
}
return (
<div>
<center>
<h1>Redux</h1>
<h1>{count}</h1>
<button className="btn btn-primary" onClick={handleIncrement}>Increment</button>
<button className="btn btn-warning" onClick={handleDecrement}>decrement</button>
</center>
</div>
);
}
export default Counter;
Upvotes: 4