0

I have an api to return the result which is the nested object. And initially state is as shown below:

const [obj, setObj] = useState({
     name: null,
     age: null,
     address: {
         city: null,
         zipCode: null
     }
})

Once the api gets called and return the result which contains all the properties, we will call setObj. Do we need to call like setObj({...obj, results}) or we can call setObj(results) directly?

Per my unerstanding, state is immutable in react and we cannot modify it directly. Please correct me if I am wrong. a smiliar quesiton I found is Why can't I directly modify a component's state, really?

thanks in advance.

Emile Bergeron
  • 17,074
  • 5
  • 83
  • 129
Yang Wang
  • 580
  • 4
  • 14

1 Answers1

3

If the object returned by the API contains only a subset of the existing properties, such as

{
  name: 'foo'
}

then you would need to spread the existing object into the new state to retain the old null properties.

setObj({ ...obj, ...results });

You'd also need to factor in deep cloning the address if needed - remember that spread only creates a shallow copy, not a deep copy.

If the object returned by the API contains all the properties, then you don't care about anything in the previous object with nulls, so you'd just need

setObj(results);
Emile Bergeron
  • 17,074
  • 5
  • 83
  • 129
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • We should also use the lambda variant rather than `setObj({ ...obj, ...results });` so that it gets updated `obj` – Vivek Bani Jul 06 '21 at 04:47
  • The function version is only necessary if the scope of this setter is within a stale closure. I wouldn't put it in unless it's necessary, and nothing in the question indicates such a thing, so I'd leave it out. – CertainPerformance Jul 06 '21 at 04:51
  • The question mentioned fetching data with API, so high probability it will be inside useEffect, so updating the state with lambda is an important point – Vivek Bani Jul 06 '21 at 04:56