I'm not able to find/print the length of an array of objects that set by ReactJS setState
. My ponent.js is as follows
import React from 'react';
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
loading: true,
error: false,
items: []
};
}
ponentDidMount() {
fetch('http://localhost:8000/api/v2/pages/1')
.then(response => response.json())
.then(data => this.setState({ items: data }));
}
render() {
console.log(this.state.items.content.length); // Gives error that says this.state.items is not defined
return (
<React.Fragment>
</React.Fragment>
);
}
}
export default MyComponent;
When I console log this.state.items
I get the following object
{
"id": 12,
},
"title": "My Title",
"content": [
{
"type": "full_richtext",
"id": "6e971101"
},
{
"type": "button",
"id": "c0f6083d"
}
]
}
What I'm trying to achieve is to get the length of the array 'content' within inside the object set by setState
.
Back Story:
My goal is to handle the asynchronous nature of setState
by writing a condition like following inside render()
if(this.state.items.content.length > 0){
//access values from this.state.items
}
So that the values are read-only when the condition is true i.e we have value inside the object.
I'm not able to find/print the length of an array of objects that set by ReactJS setState
. My ponent.js is as follows
import React from 'react';
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
loading: true,
error: false,
items: []
};
}
ponentDidMount() {
fetch('http://localhost:8000/api/v2/pages/1')
.then(response => response.json())
.then(data => this.setState({ items: data }));
}
render() {
console.log(this.state.items.content.length); // Gives error that says this.state.items is not defined
return (
<React.Fragment>
</React.Fragment>
);
}
}
export default MyComponent;
When I console log this.state.items
I get the following object
{
"id": 12,
},
"title": "My Title",
"content": [
{
"type": "full_richtext",
"id": "6e971101"
},
{
"type": "button",
"id": "c0f6083d"
}
]
}
What I'm trying to achieve is to get the length of the array 'content' within inside the object set by setState
.
Back Story:
My goal is to handle the asynchronous nature of setState
by writing a condition like following inside render()
if(this.state.items.content.length > 0){
//access values from this.state.items
}
So that the values are read-only when the condition is true i.e we have value inside the object.
Share Improve this question edited Sep 25, 2019 at 16:12 Priom Sarkar 3423 silver badges15 bronze badges asked Sep 25, 2019 at 16:00 Lalas MLalas M 1,1741 gold badge16 silver badges32 bronze badges5 Answers
Reset to default 4Because this.state.items
starts out as an empty array (which is strange, since later on it looks like its an object) You first need to make sure this.state.items.content
is defined
Do it like this:
console.log(this.state.items.content && this.state.items.content.length);
Or in your actual case
if(this.state.items.content && this.state.items.content.length > 0){
//access values from this.state.items
}
Hope this helps
The state is being initialized as an array but you're accessing content
(which is undefined
):
{
loading: true,
error: false,
items: []
};
To avoid making an further changes, initialize the state so it follows the same structure as the response. For example:
{
loading: true,
error: false,
items: { content: [] }
};
Remember that in the first render your items array is empty and the prop content doesnt exist. So maybe you have to check the length after you ve been fetched the data correctly:
ponentDidMount() {
fetch('http://localhost:8000/api/v2/pages/1')
.then(response => response.json())
.then(data => this.setState({ items: data , itemsLength: data.content.length}));
}
so when you want to check the lenght you have to check that this.state.itemsLength is different from null or from the initial state.
During first render the items array is empty and as such when you try to access the property content of items it doesn't exist that's why you get the undefined error. to overe this, you first of all check for it presence before calculating the length. ie
if (this.state.items.content && (this.state.items.content.length > 0))
Keep in mind the order of lifecycle function calls in a React Component. During the initial mounting phase, render()
is called before ponentDidMount()
. So then, the first time your ponent is rendered, items is simply an empty array and items.content is undefined.
You could then write a condition like so:
if (this.state.items.content !== undefined && this.state.items.content.length > 0) {
//access values from this.state.items
}