React Context - Context和Child render没有更新。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了React Context - Context和Child render没有更新。相关的知识,希望对你有一定的参考价值。

我在玩 REACT上下文 当我按下Child组件上的按钮时,试图将一个登录从Child组件更新到App组件。

完整的代码 此处.

所以有两个组件。App和Child在同一个文件中。

下面是我的UserContext,其中有登录变量和更新登录的函数(用loginUpdated)。

const UserContext = React.createContext({
    login: 'defaultLogin',
    updateLogin: (loginUpdated) => {}
});

在App组件中,我已经让我的UserContext.Provider围绕着Child组件。

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

        this.appLoginUpdate = this.appLoginUpdate.bind(this); 

        this.state = {
            login: "AppLoginValue"
        }
    }

    appLoginUpdate(login) {
        console.log("1. appLoginUpdate method => login value: ", login)

        this.setState({
            login: login
        })

        console.log("2. appLoginUpdateLogin method after state update :", this.state.login)
    }

    render() {
        const contextValue = {
            login: "contextValueLogin",
            updateLogin: this.appLoginUpdate
        }
        return (
            <UserContext.Provider value={contextValue}>
                <Child />
            </UserContext.Provider>
        );
    }
}

最后,我已经得到了Child组件

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

        this.handleClick = this.handleClick.bind(this);
    }

    static contextType = UserContext;

    handleClick() {
        this.context.updateLogin("ChildValueLogin")
    }

    render() {
        console.log("3. Context login value : ", this.context.login)
        return (
            <div>
                <h1>{this.context.login}</h1>
                <button onClick={this.handleClick}>UPDATE LOGIN</button>
            </div>
        )
    }
}

在点击 "UPDATE LOGIN "按钮之前,我在控制台得到了这个。

3. Context login value :  contextValueLogin 

[ 很好,这是App中给contextValue.login的值。]

当第一次点击 "UPDATE LOGIN "按钮时,我在控制台得到了这个。

1. appLoginUpdate method => login value:  ChildValueLogin 

[这是确定的,登录参数的预期值]

2. appLoginUpdateLogin method after state update : AppLoginValue

[这很糟糕,this. state has not been updated]

3. Context login value :  contextValueLogin 

[这也很糟糕]

当我再次点击:

1. appLoginUpdate method => login value:  ChildValueLogin

[ 再次确定 ]

2. appLoginUpdateLogin method after state update : ChildValueLogin

[现在第二次点击后就可以了吗?]

3. Context login value :  contextValueLogin

[又坏了,一直没有更新]

我想请你帮我找出我在这段代码中的问题,请。谢谢你的帮助。

答案

setState 异步更新状态。将setState函数改为

this.setState({
      login: login
}, () => {
      console.log(
        "2. appLoginUpdateLogin method after state update :", this.state.login
     );
});

来查看改变后的状态。

setState 函数需要一个可选的回调函数参数,该参数被称为 更新后. 如果你想在更新状态后立即看到它的变化,你需要把你的 console.log 语句在这个回调函数中

你还需要改变

const contextValue = {
    login: "contextValueLogin",           <----- hard-coded string
    updateLogin: this.appLoginUpdate
};

const contextValue = {
  login: this.state.login,
  updateLogin: this.appLoginUpdate
};

的更新值,以记录 this.context.login

进行上述修改后,控制台的输出将是。

点击更新按钮前

3. Context login value :  AppLoginValue

更新按钮后点击

1. appLoginUpdate method => login value:  ChildValueLogin 
3. Context login value :  ChildValueLogin 
2. appLoginUpdateLogin method after state update : ChildValueLogin

以上是关于React Context - Context和Child render没有更新。的主要内容,如果未能解决你的问题,请参考以下文章

包含 Context.Provider 和 Context.Consumer 的 React Context 测试组件

React 库中的 context 和 updater 参数是啥?

React Context - Context和Child render没有更新。

React Context:提供 Api Manager 的实例

React Context 和 useContext

React 的 Context API Cosumer 没有渲染 Children