Reputation: 944
I know that setState is async, but is there anyway (without Redux) to invoke setState after the executing another function before like below:
handleOpenUpdateItem = (item) => {
const { getImageByItemId } = this.props;
getImageByItemId(item.id);
this.setState({ updateMode: true, item });
};
Greetings!
Upvotes: 0
Views: 1189
Reputation: 197
As it's already mentioned in comments, you could use callbacks to make sure that this.setState
is executed after your function finishes (using Promises
or async/await
would be great options too). This is the examlpe of how it could be implemented:
getImageByItem = (id, callback) => {
// Do something here
// And return your image, or anything you want through callback like so:
callback(yourImage)
}
handleOpenUpdateItem = (item) => {
const { getImageByItemId } = this.props;
getImageByItemId(item.id, (image) => {
this.setState({ updateMode: true, item });
});
};
So you change your getImageByItem
function to include callback, and then in the handleOpenUpdateItem
you use this callback and setState inside it.
EDIT FOR 2019
As @Levitator Imbalance mentioned below, it's probably better to use Promises
, so you could implement it like so:
Without async/await:
getImageByItemId = (id) => {
return new Promise((resolve, reject) => {
// Do something with your id/image, then resolve
resolve()
// Or reject when some error happens
reject()
})
}
handleOpenUpdateItem = (item) => {
const { getImageByItemId } = this.props;
getImageByItemId(id)
.then(() => {
this.setState({ updateMode: true, item });
})
.catch(() => {
// ... handle your reject here
})
};
Or you could use async/await
like so:
Async/Await:
getImageByItemId = (id) => {
return new Promise((resolve, reject) => {
// Do something with your id/image, then resolve
resolve()
// Or reject when some error happens
reject()
})
}
handleOpenUpdateItem = async (item) => {
const { getImageByItemId } = this.props;
let something = await getImageByItemId(item.id)
// or just:
// await getImageByItemId(item.id)
this.setState({ updateMode: true, item });
};
Upvotes: 1
Reputation: 1794
Turn your handleOpenUpdateItem
to an async
function. Then you can write synchronous code inside of it.
async handleOpenUpdateItem(item) {
const { getImageByItemId } = this.props;
const item = await getImageByItemId(item.id); // wait for the call to the backend to finish
this.setState({ updateMode: true, item });
};
Upvotes: 1
Reputation: 177
You could make handleOpenUpdateItem async and use await for getImageByItemId.
Upvotes: 0
Reputation: 175098
this.setState()
being async means that you cannot normally execute things after it and expect them to happen only after the setState had completed its course. Doing things before the setState and then calling setState (exactly like you did) will work out of the box.
Upvotes: 0