Within a React App component, I am calling an API and storing the response within a local state. I then want to destructure the object that is stored in that state, but I can't just destructure right below the useEffect because it will throw an error before the call is completed.
Also, I don't want to break up the object within the useEffect, because I want the entire response for other things.
Here is an example:
const MyComponent = () => {
const [calledObj, setCalledObj] = useState({})
useEffect(() => {
//Calling API here and setting object response as calledObj State
setCalledObj(apiResponse)
}, []);
//This will throw an error when the API response has not been sent back yet.//
// While this would be easy to write the whole path in the return, the actual path is really long.//
const { name } = calledObj.person
return (<div>{name}</div>)
}
Where can I destructure or how can I work around this?
You can use optional chaining and/or the nullish coelescing operator to work around it.
Note: IE doesn't support either of these, but babel will polyfill them.
const { name } = calledObj?.person ?? {};
?.
in calledObj?.person
) prevents it from blowing up if calledObj
is undefined.??
) returns {}
if calledObj.person
isn't there.With this combination the right side is guaranteed to evaluate to an object, so the destructuring on the left never blows up.
let calledObject; // undefined;
// name is undefined, but it doesn't blow up.
const { name: name1 } = calledObject?.person ?? {};
console.log(`name 1: ${name1}`); // name 1: undefined
// ----------------
// now it's an object, but doesn't have a person property
calledObject = {};
// name is still undefined, still doesn't blow up.
const { name: name2 } = calledObject?.person ?? {};
console.log(`name 2: ${name2}`); // name 1: undefined
// ----------------
// with person.name present…
calledObject.person = { name: 'joe' };
const { name: name3 } = calledObject?.person ?? {};
// …it works as you'd expect
console.log(`name 3: ${name3}`); // name 3: 'joe'