1

I have an app that fetches data from the API. There is no safe default value that I can assign to a piece of state, because the API may return any value. As a solution, I want to set an element of state to true after completing the API call.

const [data, setData] = useState<any>()
const [dataLoaded, setDataLoaded] = useState(false)
useEffect(() => {
  setDataLoaded(false)
  Promise.resolve("myData").then(res => {
    setData(res)
    setDataLoaded(true)
  })

  }
}, [])

Will the following code, is it guaranteed that dataLoaded will be set to true only after data is populated? I understand that I can't, for example, guarantee myself access the contents of data in the call to setDataLoaded, but does that mean that the state changes themselves can execute in any order?

If not, how can I guarantee that it will be?'

I know that this guarantee does exist in class components, but I don't know if it does in hooks, especially if it's happening inside a promise.

some
  • 83
  • 1
  • 7
  • 1
    Short answer: yes. React may batch some updates, but won't change their order. – FZs Jan 17 '22 at 21:48
  • 2
    Does this answer your question? [Does React keep the order for state updates?](https://stackoverflow.com/questions/48563650/does-react-keep-the-order-for-state-updates) – deeBo Jan 17 '22 at 21:55
  • @deeBo I did read the answer to that question, but all of the answers and examples are for class components. I couldn't find an equivalent question for hooks, and I don't know what, if anything, has changed. – some Jan 17 '22 at 21:57
  • Ah, I get you, sorry - and thanks for editing the q. :) I believe what FZs says is true, though I am struggling to find concrete docs to back that up – deeBo Jan 17 '22 at 22:03
  • One way to definitely get around this is to model your state like this: `const [apiResult, setApiResult] = useState({ dataLoaded: false, data: undefined })` and, after the fetch `setApiResult({ dataLoaded: true, data: res })` - this guarantees you'll have no ordering problems *and* solves the problem in one re-render rather than two :) – deeBo Jan 17 '22 at 22:04
  • how about writing a custom hook so you don't have to do so much work every time you need an asynchronous value? see [this Q&A](https://stackoverflow.com/a/70522077/633183) for a helpful technique. – Mulan Jan 17 '22 at 22:30
  • React class component, or function component, it's all the same React framework essentially. All React components adhere to the same rules for state and lifecycle. – Drew Reese Jan 18 '22 at 08:53

0 Answers0