简体   繁体   中英

Invoke setState after function

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!

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 }); 
  };

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 });
};

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.

您可以使handleOpenUpdateItem异步,并为getImageByItemId使用await。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM