Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change React context programmatically?

I'm trying to use the new React context to hold data about the logged-in user.

To do that, I create a context in a file called LoggedUserContext.js:

import React from 'react';


export const LoggedUserContext = React.createContext(
  );

And sure enough, now I can get access to said context in other components using consumers, as I do here for example:

  <LoggedUserContext.Consumer>
       {user => (
       (LoggedUserContext.name) ? LoggedUserContext.name : 'Choose a user or create one';
       )}
   </LoggedUserContext.Consumer>

But obviously, for this system to be useful I need to modify my context after login, so it can hold the user's data. I'm making a call to a REST API using axios, and I need to assign the retrieved data to my context:

axios.get(`${SERVER_URL}/users/${this.state.id}`).then(response => { /*What should I do here?*/});

I see no way to do that in React's documentation, but they even mention that holding info of a logged in user is one of the use cases they had in mind for contexts:

Context is designed to share data that can be considered “global” for a tree of React components, such as the current authenticated user, theme, or preferred language. For example, in the code below we manually thread through a “theme” prop in order to style the Button component:

So how can I do it?

like image 374
kace91 Avatar asked Apr 03 '18 12:04

kace91


People also ask

How do you modify a context React?

To update a React Context from inside a child component, we can wrap the React Context provider around the child components. Then we set the value prop of the context provider to the the state setter function that lets us update the context value. Then we can use the useContext hook to access the context.

How do you update context value?

Updating Context value js components, we cannot update this value. To switch between the two theme types, we need to pass a function as well. This function will allow us to switch between both themes. So we need to pass this function along with the dark theme via the Provider component.

How do you use context outside of component?

To access a React context outside of the render function, we can use the useContext hook. We create the UserContext by calling the React. createContext method with a default context value. Then in the Users component, we call the useContext hook with UserContext to accxess the current value of UserContext .


2 Answers

In order to use Context, you need a Provider which takes a value, and that value could come from the state of the component and be updated

for instance

class App extends React.Component {
   state = {
      isAuth: false;
   }
   componentDidMount() {
      APIcall().then((res) => { this.setState({isAuth: res}) // update isAuth })
   }
   render() {
       <LoggedUserContext.Provider value={this.state.isAuth}>
           <Child />
       </LoggedUserContext.Provider>
   }
}

The section about dynamic context explains it

like image 50
Shubham Khatri Avatar answered Sep 22 '22 09:09

Shubham Khatri


Wrap your consuming component in a provider component:

import React from 'react';

const SERVER_URL = 'http://some_url.com';

const LoggedUserContext = React.createContext();

class App extends React.Component {
    state = {
        user: null,
        id: 123
    }
    componentDidMount() {
        axios.get(`${SERVER_URL}/users/${this.state.id}`).then(response => { 
            const user = response.data.user; // I can only guess here
            this.setState({user});
        });
    }
    render() {
        return (
            <LoggedUserContext.Provider value={this.state.user}>
                <LoggedUserContext.Consumer>
                    {user => (
                        (user.name) ? user.name : 'Choose a user or create one';
                    )}
                </LoggedUserContext.Consumer>
            </LoggedUserContext.Provider>
        );
    }
}

I gave a complete example to make it even clearer (untested). See the docs for an example with better component composition.

like image 39
Hinrich Avatar answered Sep 26 '22 09:09

Hinrich