反应上下文-上下文和子渲染未更新

时间:2020-05-23 13:23:23

标签: reactjs react-context

我正在与REACT context一起玩,试图在按下“子”组件上的按钮时将登录从“子”组件更新为App组件。

完整代码here

因此,在同一文件中有两个组件:App和Child。

这是我的UserContext,其中包含login变量和用于更新登录名的功能(使用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赋予的值]

第一次单击“更新登录”按钮时,我已经在控制台中找到了它:

1. appLoginUpdate method => login value:  ChildValueLogin 

[可以,登录参数的期望值]

2. appLoginUpdateLogin method after state update : AppLoginValue

[不好,此状态尚未更新]

3. Context login value :  contextValueLogin 

[也很糟糕]

当我再次单击时:

1. appLoginUpdate method => login value:  ChildValueLogin

[再次确定]

2. appLoginUpdateLogin method after state update : ChildValueLogin

[现在第二次单击就可以了吗?! ]

3. Context login value :  contextValueLogin

[再次糟糕,从未更新]

我希望您能帮助我找出此代码中的问题。谢谢您的帮助。

1 个答案:

答案 0 :(得分:0)

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