React useContext returns undefined

nayiaw picture nayiaw · Aug 5, 2019 · Viewed 9.8k times · Source

I'm trying to use React Context to manage states for my project, but I can't seem to make it work for my CRA codebase this time while I had successful attempts on other projects. useContext returns undefined so I couldn't access the values inside the context, but I have double checked that my Provider is at my app root level. Appreciate any help.

This is my simplified App component:

import React, { useContext } from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import './App.css';

import { PlayerContextProvider, PlayerContext } from 'contexts/PlayerContext';

const App = () => (
  <PlayerContextProvider>
    <Test />
    <Router>
      <Switch>
        <Route path="/" exact component={Home} />
      </Switch>
    </Router>
  </PlayerContextProvider>
);

const Test = () => {
  const values = useContext(PlayerContext);
  console.log('test values', values); // returns undefined!

  return <div>Hello World</div>;
};

export default App;

This is my context:

import React, { useState, createContext } from 'react';

const PlayerContext = createContext();

const PlayerContextProvider = ({ children }) => {
  const [players, setPlayers] = useState(['test']);

  const addPlayer = ({ name }) => {
    setPlayers([...players, { name }]);
  };

  const values = { players, addPlayer };
  console.log('context values', players); // shows ['test'] here

  return (
    <PlayerContext.Provider values={values}>
      <>
        {players}
        {children}
      </>
    </PlayerContext.Provider>
  );
};

export { PlayerContextProvider, PlayerContext };

Answer

Vencovsky picture Vencovsky · Aug 5, 2019

You have a small typo.

Instead of values the correct is value without s.

<PlayerContext.Provider value={values}>

Edit:

If you are getting undefined and isn't because of the typo, you probably forgot to "wrap" a component with the Provider and the undefined value comes from the first argument of React.createContext() (which is undefined is you don't pass anything)