'useState – Are nested values rolled out progressively?
I'm getting a TypeError, and I can't figure out why:
TypeError: undefined is not an object (evaluating 'data.nested.value')
The above error occurred in the <MyComponent> component:
I am aware that one can't read properties of null-ish values (null and undefined). The problem is that neither data, nor data.nested isn't supposed to be null-ish in the first place, – I'm using TypeScript with "strict": true, so I'm pretty sure in that (also, I've logged the value).
My setup is that I have a component, which uses a custom hook, which in turn fetches some data from server (the indicated key lines are explained below):
interface Data {
nested: { value: string }; // (1)
}
export function MyComponent() {
const data = useData();
if (data == null) return null; // (2)
return (
<MyOtherComponent
prop={data.nested.value} // (3)
/>
);
}
import { useState, useEffect } from 'react';
import { getData } from './api/get-data';
export function useData() {
const [data, setData] = useState<Data>(); // (4)
useEffect(() => {
(async () => {
const result = await getData(); // (5)
if (result.error) {
console.error(result.error);
} else {
setData(result.value);
}
})();
}, []);
return data ?? null // (6)
}
Datainstances are defined to have.nestedproperty, which is always an object, and is nevernullorundefined.- The
dataitself, however, can benull(see(4)and(6)). If it is, then<MyComponent />shouldn't render anything (i.e.,return null).- if I change
if (data == null)toif (!data?.nested)the error goes away. But in the real app I have not just one but many.nestedproperties, so this explicit check would be unreadable. Also, this would be a weird check, since it shouldn't be null-ish in the first place.
- if I change
- The value
data.nested.valueis used in<MyOtherComponent />, – this is where the error is thrown. - The get/set suite for
datais created with React'suseState. There's no initialiser provided, sodatais initiallyundefined. - The
getDataAPI function never throws and resolves to a utility object with.valueand.errorproperties (similar to howPromise.allSettledworks).- most importantly, the
.valueis always a complete instance ofDatawith all of its properties, returned from the server.
- most importantly, the
- If
datais not set (isundefined), the hook returnsnullinstead.
Given all that, there seems to be a point where data is an object, but data.nested is null-ish. I'm pretty sure, in plain JavaScript this is impossible. But maybe React adds something on its own? Such as, for example, progressive rollout of nested values?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
