React 上下文 - 上下文和子渲染未更新

React Context - Context and Child render are not updating

我正在尝试 REACT context 当我按下子组件上的按钮时尝试将登录从子组件更新到 App 组件。

完整代码here.

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

这是我的带有登录变量的 UserContext 和更新登录的函数(使用 loginUpdated)

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

在 App 组件中,我的 UserContext.Provider 围绕着子组件 :

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

最后我得到了子组件

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还没有更新]

3. Context login value :  contextValueLogin 

[这也很糟糕]

当我再次点击时:

1. appLoginUpdate method => login value:  ChildValueLogin

[再次确定]

2. appLoginUpdateLogin method after state update : ChildValueLogin

[现在点两下就OK了?! ]

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