JS状态意外更新

时间:2019-05-15 16:02:52

标签: javascript reactjs components state

我是JS的新手。

这是我正在处理的页面:

import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import Plot from 'react-plotly.js';
import { fetchPosts, createPost } from '../actions/postActions'

import GroupedBarChart from '../containers/GroupedBarChart'

class Usage extends Component {
    state = {
        title: '',
        resp_data: [],
    }

    componentDidMount() {
        this.props.fetchPosts('/en/api/usage/')
    }

    componentWillReceiveProps (nextProps) {
        if (nextProps.posts.data) {
            this.setState({resp_data: nextProps.posts.data}, function () {
                console.log(this.state.resp_data);
            });
        }
        console.log(this.state.resp_data)
    }

    render() {
        const { title, resp_data } = this.state

        return (<div>
            <GroupedBarChart
                title={ title }
                data={ resp_data }
            />
        </div>);
    }
}

const mapStateToProps = state => ({
    posts: state.posts.items,
    newPost: state.posts.item
})

export default connect(mapStateToProps, { fetchPosts, createPost })(Usage)

这样做的问题是状态在某个时刻意外地改变。

因此在componentWillReceiveProps调用之后的console.log中有一个setState,这个console.log的输出正是我所期望的。但是,如果我在if语句后立即打印状态:

if (nextProps.posts.data) {
    this.setState({resp_data: nextProps.posts.data}, function () {
        console.log(this.state.resp_data);
    });
}

this.state.resp_data是一个空数组。

两个console.logs的输出如下:

[] # this is outside if
(2) [{…}, {…}] # this is inside if

有人可以向我解释为什么会发生这种情况,我该如何克服呢?

谢谢。

2 个答案:

答案 0 :(得分:1)

首先摆脱componentWillReceiveProps方法,因为不建议再使用它,它将在版本17中删除。您可以检查here以获得更多信息。

第二次检出react lifecyles,因此您将看到您的组件将在安装阶段使用初始数据进行渲染,因此我假设您一开始没有posts.data,并且在componentDidMount处进行了获取。因此,在获取数据之后,您将触发setState,这会导致另一个渲染(检查生命周期更新阶段,您将看到setState导致渲染)。

您在致电console.log之后希望看到一些数据后再致电setState,但是如果您查看其中的documentation,将会发现并不能保证。

  

setState()并不总是立即更新组件。它可能   批处理或将更新推迟到以后。这使得阅读this.state   在调用setState()之后立即陷入潜在的陷阱。

答案 1 :(得分:0)

由于某种原因,当我将后端的响应更改为data = []data = {}时,它已经起作用了。我仍然对为什么会感到困惑。