-
Currently, we need to set an initial value when defining primitive atoms. However, if the atom will always be hydrated by An easy workaround is setting an arbitrary initial value like: const someAtom = atom<number>(0); // 0 is not important and never used. However, if the atom's value type is complex, it becomes messy to set a complex initial value that will never be used. Another simple approach is setting null as a non-initialized value: const someAtom = atom<SomeComplexType | null>(null); The drawback here is that we need to write null-case logic wherever we use this atom because the atom's value type becomes nullable. This discussion #581 gave me an idea using To reiterate, for atoms that should be hydrated, it would be very useful if they could be initialized without an initial value, and if read before initial writing, they would throw an error. Appendix: my workaround code import { atom } from 'jotai';
const INITIAL_VALUE_NON_PRIMITIVE = {} as const;
type InitialValueNonPrimitive = typeof INITIAL_VALUE_NON_PRIMITIVE;
/**
* Create an atom without initial value that throws an error if read before initialization.
* @returns An atom that throws an error if read before initialization.
*/
export const atomWithNoInitialValue = <Value>() => {
const baseAtom = atom<Value | InitialValueNonPrimitive>(
INITIAL_VALUE_NON_PRIMITIVE,
);
return atom<Value, [newValue: Value], void>(
(get) => {
const value = get(baseAtom);
if (value === INITIAL_VALUE_NON_PRIMITIVE) {
throw new Error(
'atomWithNoInitialValue was read before initialization',
);
}
return value as Value;
},
(_get, set, newValue) => {
set(baseAtom, newValue);
},
);
}; |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
Your workaround seems good. I would use We have |
Beta Was this translation helpful? Give feedback.
Your workaround seems good. I would use
Symbol()
instead of{}
.We have
atomWithPending
(injotai-suspense
, but it can be defined pretty easily.)But, I'm not sure if it works with
useHydrateAtoms
.