0

In React, I'm making an async API call, updating a React state, and then running a function in a following .then() that uses that React state. However, the function runs without the updated state data, even though it's in a then. Why is this?

You can see below, how I originally wrote my function. But sortArray runs without the updated foods state.

const [foods, setFoods] = useState([]);

 api
    .getFood('fruits')
    .then((res) => {
      setFoods(res);
     })
    .then(() => sortArray(foods));

Instead, I needed to do the below code, that is, write an updater useEffect that waits until the state is set, and then runs the sortArray function, which for some reason has the updated foods state.

const [foods, setFoods] = useState([]);

 api
    .getFood('fruits')
    .then((res) => {
      setFoods(res);
     })
    .then(() => setNeedsSorting(true));

  // cue up sort function
  useEffect(() => {
    if (needsSorting) {
      setNeedsSorting(false);
      sortArray();
    }
  }, [needsSorting, sortArray]);

const sortArray = useCallback(() => {...sorts the foods array...})

Why is all this necessary? And how does this successfully grab the updated state, when the original code couldn't?

Thanks in advance for the help.

Cjmaret
  • 142
  • 9
  • 1
    Does this answer your question? [The useState set method is not reflecting a change immediately](https://stackoverflow.com/questions/54069253/the-usestate-set-method-is-not-reflecting-a-change-immediately) – Konrad Dec 04 '22 at 19:55
  • 1. You never return anything from that `then` callback, so there is nothing to await. 2. `setFoods` doesn't return a promise, so you can't use `then` anyway. 3. You can't await for state to update. It will be updated in the next render cycle – Konrad Dec 04 '22 at 19:56
  • @Konrad: then's callback [doesn't even have to return anything](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then), yet then will return a promise. Your 2. is misleading. – Wiktor Zychla Dec 04 '22 at 19:59
  • Your 3. is correct though. – Wiktor Zychla Dec 04 '22 at 20:00
  • @WiktorZychla, you are right, what I meant is that the next `then` won't wait if nothing is returned – Konrad Dec 04 '22 at 21:02
  • thanks guys, but I also noticed that when I don't put ```setNeedsSorting``` in a ```then``` (just after the api call inside the function), the sorting happens before the state is set... so it seems like the ```then``` is doing something for ```setNeedsSorting```... – Cjmaret Dec 06 '22 at 18:28

0 Answers0