调用父方法时,子setState不起作用

时间:2019-05-31 16:46:01

标签: reactjs

我是React的新手,如果这是一个不好的问题,请对不起。我在更改子组件的状态,然后调用更改父组件的状态的方法时遇到麻烦。现在,当我触发应该更改状态的方法时,父状态会按原样更改,但子状态根本不会更改。

当我删除“父”组件上的状态更改时,子组件也会按需更改。

这是父组件(已编辑以删除与该问题无关的代码)

class Parent extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            loginModalName: "Log in"
        }
        this.bindedUpdateModalName = this.updateModalName.bind(this)
    }

    updateModalName(name) {
        console.log(name);
        this.setState({
            loginModalName: name
        });
    };

    render() {
        return (
            <Child loginSwitch = {this.bindedUpdateModalName}/>
        );
    }
}

这是子组件

class Child extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            isLoggingIn: true
        }
    }

    toggleLoggingIn = () => {
        this.setState({
            isLoggingIn: !this.state.isLoggingIn
        });
        console.log(this.state.isLoggingIn);
        this.props.loginSwitch(this.state.isLoggingIn ? "Log in" : "Register");
    };

    render() {
        return (
            <Button onClick={this.toggleLoggingIn} type="link" style={{paddingLeft: 0}}>register now!</Button>
        );
    }

没有错误消息,但我的日志显示

true
Log In

每次我单击按钮

2 个答案:

答案 0 :(得分:3)

这是因为setState是异步的。您需要等待状态更改发生(setStatecomponentDidUpdate的第二个回调选项),或者可以使用isLogin之类的变量来保存新的状态值。将您的处理程序更改为此

toggleLoggingIn = () => {
    const isLogin = !this.state.isLoggingIn
    this.setState({
        isLoggingIn: isLogin
    });
    console.log(this.props.loginSwitch);
    this.props.loginSwitch(isLogin ? "Log in" : "Register");
};

Check it out in action!

您遇到的问题是尝试在antd表单上使用本地状态。您应该使用父状态并通过它作为道具,或者使用antd方法在HOC上更新“状态”

答案 1 :(得分:2)

正如约翰所说,setStateasync。但是,setState在更新状态后需要另一个参数callback function来调用。

来自docs

  

setState()的第二个参数是可选的回调函数,将在setState完成并重新呈现组件后执行。通常,我们建议将componentDidUpdate()用于此类逻辑。

尝试一下:

toggleLoggingIn = () => {
    const isLogin = !this.state.isLoggingIn
    this.setState(
        {
            isLoggingIn: !this.state.isLoggingIn
        },

        // Callback to run after state has been updated 
        () => {
            console.log(this.state.isLoggingIn);
            this.props.loginSwitch(this.state.isLoggingIn ? "Log in" : "Register");
        }
    );
};