Reputation: 2016
I am very new to JS.
Here is a page that I am working on:
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)
The problem with that is that the state changes unexpectedly at some point.
So in componentWillReceiveProps
there is a console.log
immediately after the setState
call and the output of this console.log is exactly what I expect. However, if I print the state immediately after the if statement:
if (nextProps.posts.data) {
this.setState({resp_data: nextProps.posts.data}, function () {
console.log(this.state.resp_data);
});
}
this.state.resp_data
is an empty array.
The output of the two console.logs looks like that:
[] # this is outside if
(2) [{…}, {…}] # this is inside if
Can someone explain me why this happens and how can I overcome it?
Thanks in advance.
Upvotes: 0
Views: 48
Reputation: 5857
First of get rid of componentWillReceiveProps
method as it is not recommended to use anymore and it will be remove at version 17. You can check here for extra information.
Secondly checkout react lifecyles so you will see your component will render with initial data at mounting phase, so I assume you have no posts.data
at first and you fetch it at componentDidMount
. So after you fetched data you trigger setState
which cause another render (check lifecycle updating phase you will see setState cause render).
You call console.log
after calling setState
and expecting to see some data but if you look at the documentation of it you will see it is not guarantee.
setState() does not always immediately update the component. It may batch or defer the update until later. This makes reading this.state right after calling setState() a potential pitfall.
Upvotes: 1
Reputation: 2016
For some reason when I changed the response in the back end - data = []
to data = {}
it has worked. I am still confused of why would that be.
Upvotes: 0