【问题标题】:JS state updates unexpectedlyJS 状态意外更新
【发布时间】:2019-10-02 20:13:32
【问题描述】:

我对 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 中,在setState 调用之后立即有一个console.log,这个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

谁能解释一下为什么会发生这种情况,我该如何克服?

提前致谢。

【问题讨论】:

  • 组件的状态永远不会在 componenetDidMount() 中设置(除了您的默认值),您需要在 this.props.fetchPosts() 完成后 setState({resp_data: responseData}) 跨度>
  • 你的意思是我有正确的 nextProps.posts.data 但状态是空的?
  • 是的nextProps.posts.data 是正确的,那么它会正确设置状态,但是一旦退出 if 语句 - 状态就是空的
  • @VnC 这是你在尝试什么? if (nextProps.posts.data) { this.setState({resp_data: nextProps.posts.data}, function () { console.log(this.state.resp_data); }); } console.log(this.state.resp_data);第二个 console.log 不工作?
  • 这里 this.setState 第二个参数是回调函数,它是异步的。因此,您在调用 setState 后看不到具有正确数据的状态,因为您的代码继续,并且在 setState 回调之前触发了第二个 console.log。

标签: javascript reactjs components state


【解决方案1】:

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

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

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

setState() 并不总是立即更新组件。有可能 批处理或推迟更新。这使得阅读 this.state 就在调用 setState() 之后,这是一个潜在的陷阱。

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2019-01-17
      • 2021-07-20
      • 1970-01-01
      • 1970-01-01
      • 2021-07-30
      • 2016-03-12
      • 2021-09-11
      • 2022-11-17
      • 2020-06-05
      相关资源
      最近更新 更多