简体   繁体   中英

How do I deal with promises in setState?

I have the following react code, that represents a text input.

 onChangeDestination(url, index) {
    this.setState(prevState => {
      const rules = [...prevState.rules];
      rules[index] = { ...rules[index], url};
      if (isURL(url+'')) {
        testURL(url).then(r=> {
          var url_status = r.data.response
          rules[index] = { ...rules[index], url_status};
        })
      } else {
         var url_status = "No URL"
         rules[index] = { ...rules[index], url_status};
      }
      return { rules };
    });
  };

In English:

If the URL passes isURL() validation, then use custom function testURL() to see what the HTTP status of that URL is (using axios ).

In my template, there's a {props.url_status} for the relevant bit.

The issue is, even though it's logging to the console the desired behaviour, it doesn't seem to be updating the viewport reliably, which I think is linked to the promise.

What am I doing wrong?

You could achieve it by converting your function to be asynchronous and calling your promise (if necessary) before your setState . This solution uses the easier to read async/await syntax and a ternary condition to choose the correct status value :

const url_status = isURL(url + '') ? (await testURL(url)).data.response : "No URL"

This line will execute your promise and wait for it only if isURL return true , if so it will return the response part and if not, it will send out "No URL" .

Full code :

async onChangeDestination(url, index) {
    const url_status = isURL(url + '') ? (await testURL(url)).data.response : "No URL"
    this.setState(prevState => {
        const rules = [...prevState.rules];
        rules[index] = { 
            ...rules[index],
            url,
            url_status
        };
        return { rules };
    });
};

I recommend to use more components with some particular single task only. In this case: you might need a stateless Input component with an onChange and a value prop. Its parent could be some container where the onChange triggers some async request and has a state like url_status . As @Nit commented set the state in the promise then clause. This url_status will be a prop of some other component, so in case of the prop changes that component will re-render automatically... In most of the cases you do not need to use states at all.

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