Reputation: 65
i am trying to get data from an external API and use it to change the state on my app. The data actually shows up in the console but when i run set state does not change the state of my app.
class App extends Component {
state={
jobs:[]
}
onTermSubmit=(term)=>{
const proxy=`https://cors-anywhere.herokuapp.com/`;
const api = `${proxy}https://--------/positions.json?description=${term}&page=1`;
fetch(api).then(res=>res.json()).then(data=>this.setState({jobs:data}))
console.log(this.state)
}
I am trying to get the state to change to the data returned from the API
Upvotes: 0
Views: 255
Reputation: 4147
As mentioned by @Alexander Staroselsky fetch()
and setState()
are asynchronous operations and the application won't wait until they are done to continue to the next operation thus resulting in this.state.jobs
to still be an empty array.
My solution would be to make them synchronous by adding the async/await keyword before calling he function like this.
onTermSubmit= async (term)=> {
const proxy=`https://cors-anywhere.herokuapp.com/`;
const api = `${proxy}https://--------/positions.json?description=${term}&page=1`;
let rawRes = await fetch(api)
let jsonRes = await rawRes.json()
await this.setState({jobs:rawRes}))
console.log(this.state)
}
Just another approach
Hope this is helpful
Upvotes: 0
Reputation: 38807
Both fetch()
and setState()
are asynchronous so attempting put a console.log()
statement after the expression will not wait for the fetch
or setState()
to complete/resolve. Instead you can use the callback argument of setState()
to console.log()
only after fetch
has resolved and setState()
has updated state. From the documentation:
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. Instead, use componentDidUpdate or a setState callback (setState(updater, callback)), either of which are guaranteed to fire after the update has been applied. If you need to set the state based on the previous state, read about the updater argument below.
fetch(api)
.then(res => res.json())
.then(data =>
this.setState({ jobs: data }, () => {
console.log(this.state);
})
)
.catch(err => console.log(err));
Hopefully that helps!
Upvotes: 3