setState没有立即更新状态

时间:2018-03-05 08:14:07

标签: javascript reactjs

我有简单的组件

class App extends Component {
    handleClick() {
        let banana = {message: 'banana triggered'};
        this.setState({banana});

        console.log(this); // banana is set in state!!!!
        console.log(this.state); // state is null :O
        setTimeout(() => {
            console.log(this.state); // banana is set!
        }, 5)
    }

    render() {
        const {state, actions} = this.props;

        return (
                <div>
                    {this.state && this.state.banana.message} <br />
                    <button onClick={() => this.handleClick()}>Test</button>


                    {state.alert.message && <p>{state.alert.message}</p>}
                    <p onClick={() => actions.alert.success("This is not")}>
                        This is magic
                    </p>
                </div>
        )
    };
}

export default connect(
    state => (
        {
            state: {...state}
        }
    ),
    dispatch => (
        {
            actions: {
                dispatch: dispatch,
                alert: {
                    success: text => dispatch(alert.success(text))
                }
            }
        }
    )
)(App);

问题是我需要在我的JSX渲染中添加this.state &&以检查是否存在this.state,我理解JavaScript中的常规,但在React.js中是不正常的?他应该立即对状态变化做出反应吗?另外让我感到困惑的是,来自两个console.logs,第一个(这个)有香蕉设置状态,第二个是空的。怎么样?

下图:

enter image description here

P.S。 Redux没有这样的问题,只有本地组件状态

2 个答案:

答案 0 :(得分:2)

react's docs mention状态更新是异步的。 为了根据状态的变化采取行动,react setState函数提供了一个回调,您可以按如下方式使用:

this.setState({banana}, () => {
    console.log(this.state);
});

关于你的评论,国家的价值在印刷时实际上并不存在。只有在您单击控制台see this for more deatils

中的展开箭头后才会计算该值

答案 1 :(得分:1)

根据react docs,setState()是异步的,并且在同一周期内的多个调用可以一起批处理。 如果检查更新的状态值,则可以添加回调方法

this.setState({ banana }, ()=> {
 // console.log(this.state);
 // Here's the updated state
});

在您的情况下,第一个console.log(this)未设置香蕉。 See your code in Sandbox。看起来前两个控制台日志没有显示任何状态,因为初始状态为null,异步调用完成后超时后,设置状态为banana。