Reputation: 33
when my react state is an object, I can get its property in render method, but when I set the state to array and use state[0].property in render method, it give me the undefined error, cannot figure out, any help??? Thanks!!!
class App extends Component {
state={
dataArray:[]
}
componentDidMount(){
this.getTrainInfo();
}
getTrainInfo=()=>{
fetch('https://api-v3.mbta.com/routes')
.then(response=>response.json())
.then(res=>{
//res will return an array of objects
let arr=[];
let data={};
data.destination=res.data[0].attributes.direction_destinations[0];
data.lineID=res.data[0].relationships.line.data.id
arr.push(data);
this.setState({dataArray:arr});
//I put a console.log(dataArray) here, I can get
// [{destination:xxx, lineID:xxx }] back.
})
}
render() {
//in here, I also can get the array: [{destination: xxx, lineID: xxx}]
let data=this.state.dataArray;
//but in here, I get error saying property destination is undefined,
//why?
let destination=data[0].destination;
//console.log(destination);
return (
<div className="App">
<h1>Train info</h1>
</div>
);
}
}
Upvotes: 1
Views: 1001
Reputation: 34014
You need to add condition because on initial render the dataArray is empty array and doesn’t have any objects in it.
From second render on wards you have data in dataArray so add below condition
if(this.state.dataArray.length){ //this condition will be true when dataArray length is greater than zero
let destination=data[0].destination;
console.log(destination); //this will print the value
}
Upvotes: 1
Reputation: 15698
This is normal behavior. React will render you component a single time before ever executing the logic in componentDidMount()
Which is why you're getting the undefined error because your inital state starts out as an empty array.
To resolve this, it is common practice to have a "loading state" while your component updates with the new data. So when the state is finally updated, your component will re-render and display your desired content.
In your render, try doing something like:
render() {
let data=this.state.dataArray;
if(this.state.dataArray.length == 0){
return Loading...
} else {
return (
<div className="App">
// whatever logic you want to display
<h1>Train info</h1>
</div>
)
}
Upvotes: 1