1

I recently try to implement context in my React app but I just can't access to my context on a chlid component.

The principle is as follows: The index.js provide a context who declare a value which correspond to the logged status of an user (false by default).

If App.js detects a JWT store in the localstorage, so the context is updated to true and a certain component is render.

Here is the Code:

AppContext.js

import React from 'react'

export const AppContext = React.createContext({
  isUserLogged: false
})

index.js

import React from 'react'
import ReactDOM from 'react-dom'
import './assets/sakura/app.css'
import App from './components/App'
import * as serviceWorker from './serviceWorker'
import { AppContext } from './context/AppContext'

ReactDOM.render((
  <AppContext.Provider>
      <App />
  </AppContext.Provider>
), document.getElementById('root'));

App.js

import React from 'react'
import Auth from './auth/Auth'
import Main from './main/Main'
import { AppContext } from '../context/AppContext'

class App extends React.Component {
  constructor(props) {
    super(props)

    this.state = {
        userToken: localStorage.getItem('spotlight-token'),
        isUserLogged: false
    }
}

UNSAFE_componentWillMount() {
    if (this.state.userToken) this.setState({isUserLogged: true})
}

static contextType = AppContext


render() {
    console.log(this.context)

    const isUserLogged = this.state.isUserLogged

    return isUserLogged ? <Main /> : <Auth />
}
}

export default App

But the problem is here, the console returns undefined and I don't understand why.

Thank you for your help, I know it may sound slightly stupid but I'm a pure beginner width context and really want to understand it.

5
  • Your provider doesn't have a value Commented Dec 13, 2019 at 17:52
  • Okay but the value aren't those passed in the AppContext.js ? Commented Dec 13, 2019 at 17:55
  • 1
    @RenaudMonell That's the default value, in case you forget to render a Provider. When you render a Provider, you should pass in the value you want via its value prop. Currently you don't have that prop, so you're specifying undefined. Commented Dec 13, 2019 at 17:57
  • Thank you very much ! This notion was a little cloudy now it remains for me to find how to change its value and I would be good! Commented Dec 13, 2019 at 18:07
  • @RenaudMonell pass it in as a prop. Commented Dec 16, 2019 at 9:03

1 Answer 1

2

Read the example at the official docs under the heading Updating Context from a Nested Component:

app.js

import {ThemeContext, themes} from './theme-context';
import ThemeTogglerButton from './theme-toggler-button';

class App extends React.Component {
  constructor(props) {
    super(props);

    this.toggleTheme = () => {
      this.setState(state => ({
        theme:
          state.theme === themes.dark
            ? themes.light
            : themes.dark,
      }));
    };

    // State also contains the updater function so it will
    // be passed down into the context provider
    this.state = {
      theme: themes.light,
      toggleTheme: this.toggleTheme,
    };
  }

  render() {
    // The entire state is passed to the provider
    return (
      <ThemeContext.Provider value={this.state}>
        <Content />
      </ThemeContext.Provider>
    );
  }
}

function Content() {
  return (
    <div>
      <ThemeTogglerButton />
    </div>
  );
}

ReactDOM.render(<App />, document.root);

theme-toggler-button.js

import {ThemeContext} from './theme-context';

function ThemeTogglerButton() {
  // The Theme Toggler Button receives not only the theme
  // but also a toggleTheme function from the context
  return (
    <ThemeContext.Consumer>
      {({theme, toggleTheme}) => (
        <button
          onClick={toggleTheme}
          style={{backgroundColor: theme.background}}>
          Toggle Theme
        </button>
      )}
    </ThemeContext.Consumer>
  );
}

export default ThemeTogglerButton;
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.