I was trying to fetch an array of objects when I encounter this problem. Sorry for my messy code, I'm a beginner.
export class App extends Component {
state ={
character:[]
}
componentDidMount(){
fetch('https://swapi.dev/api/people/').then(data => data.json()).then(res =>{
this.setState(() =>{
const ar = res.results
return {
character: ar
}
})
})
}
render() {
return (
<div>
test
{console.log(this.state.character[0])}
</div>
)
}
}
That code works fine for me at first until I changed the console log to {console.log(this.state.character[0].name)}
it says "cannot read property of an undefined" even though the first line displays the object perfectly
Your App
component fetches the data in componentDidMount
life cycle method which will execute after the first mount. {console.log(this.state.character[0].name)}
shows error "cannot read property of undefined
because when the component mounts for first time, the data is not available yet, which means this.state.character
is still an empty array. So when try to access this.state.character[0].name
, its like saying give me the value of undefined.name
which will give you an error because name
property does not exist on undefined
. To fix this issue you can check if character.length
in a conditional and then try to access .name
.
Example
render() {
return (
<div>
test
{this.state.character.length && <p>{this.state.character[0].name}</p>}
</div>
)
}
Fetch is asynchronous
so you will take some time to get the result but before that your jsx is called already. So it is good to use conditional jsx. Please check the complete example as below where I shown all the name of character array under li element.
export class App extends React.Component {
state = {
character: []
};
componentDidMount() {
fetch('https://swapi.dev/api/people/').then(data => data.json()).then(res => {
this.setState(() => {
const ar = res.results;
return {
character: ar
}
})
})
}
render() {
return (
<div>
test
{
this.state.character && this.state.character.length && this.state.character.map((item, index) => {
return <li key={index}>{item.name}</li>
})
}
</div>
)
}
}
export default App;
So that will not work. Data is not there yet. There are bunch of ways to workaround it. Most simple one is to have object structure predefined in the state object, which is not very dynamic. Otherwise simple .length + if + else
will do the job.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.