如何以编程方式更改React上下文?

时间:2018-04-03 12:19:42

标签: javascript reactjs login react-context

我正在尝试使用新的React上下文来保存有关已登录用户的数据。

为此,我在名为LoggedUserContext.js:

的文件中创建了一个上下文
import React from 'react';


export const LoggedUserContext = React.createContext(
  );

当然,现在我可以使用消费者访问其他组件中的所述上下文,例如我在这里:

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

但显然,为了使这个系统有用,我需要在登录后修改我的上下文,这样它就可以保存用户的数据。我正在使用axios调用REST API,我需要将检索到的数据分配给我的上下文:

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

我认为在React的文档中没有办法做到这一点,但他们甚至提到保存登录用户的信息是他们为上下文考虑的用例之一:

  

上下文旨在共享可被视为“全局”的数据   React组件树,,例如当前经过身份验证的用户,   主题或首选语言。例如,在下面的代码中我们   手动穿过“主题”道具以便设置Button的样式   成分:

那我该怎么做呢?

2 个答案:

答案 0 :(得分:8)

要使用Context,您需要Provider取值,该值可能来自组件的状态并进行更新

例如

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>
   }
}

关于dynamic context的部分解释了

答案 1 :(得分:2)

将您的消费组件包裹在提供者组件中:

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>
        );
    }
}

我给出了一个完整的例子,使它更清晰(未经测试)。有关具有更好组件构成的示例,请参阅the docs