How to fix cannot read properties of null (reading 'useContext')?
Asked Answered
C

12

23

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:

  1. You might have mismatching versions of React and the renderer (such as React DOM)
  2. You might be breaking the Rules of Hooks
  3. 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;
Cheung answered 4/11, 2022 at 20:3 Comment(1)
The context prop of the redux Provider component is for very advanced use cases only. You do not need this. In fact I can't even explain what it's for because in all my years of react-redux I have never used it.Pseudonymous
H
16

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.

Histology answered 9/6, 2023 at 8:37 Comment(6)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Tenancy
lol this was it for meArgilliferous
what if this problem happens on production? am i supposed to shut down the whole system and restart it again all the time every time it happens and disrupt UX?Dru
I would love to know more about WHY this works. For me it was during the 'build', so I used npm run build, rather than next build, and it worked perfectly. 4 HOURS trying anything and everything else.Inarticulate
No, it doesn't work for me.Dworman
Is there a solution for this? everytime shutting and restarting server is annoyingCarnage
F
3

Issue

Store isn't a React component so it can't use the useStore hook.

useStore

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.

Solution

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;
Frit answered 4/11, 2022 at 23:12 Comment(0)
S
1

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.

Superstition answered 19/7, 2023 at 15:57 Comment(0)
S
1

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

Supinator answered 10/1 at 14:41 Comment(1)
While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From ReviewCrutch
T
1

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

Toilsome answered 12/6 at 10:5 Comment(0)
I
0

I had this problem and the answer was that I accidentally installed the locked package again, deleted it and it ran

Instrumental answered 5/7, 2023 at 7:13 Comment(3)
And with what did you lock it? A bike lock? Wait, ..., no that can't be true. Did you, by any chance, mean package-lock.json? In that case add a summary why this works. For the meantime, I recommend deletion.Tracee
This does not provide an answer to the question. Once you have sufficient reputation you will be able to comment on any post; instead, provide answers that don't require clarification from the asker. - From ReviewTracee
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Tenancy
D
0

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.

Desinence answered 13/8, 2023 at 0:7 Comment(0)
F
0

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".

Foregone answered 17/9, 2023 at 8:6 Comment(0)
C
0

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!

Carabineer answered 7/10, 2023 at 17:59 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Tenancy
M
0

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.

Maharashtra answered 16/1 at 16:30 Comment(0)
T
0

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!

Topcoat answered 28/6 at 7:7 Comment(0)
F
-1

Delete and Reinstall the npm modules , Using the command = npm install, you can install npm modules.

This will resolve the error.

Fisticuffs answered 6/2, 2023 at 10:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.