Conditional useSnapshot
#914
-
|
Hi, I'm just wondering if this kind of code has been seen before. I have a proxy that may be undefined and need a snapshot of it: export function useSnapshotAcceptUndefined<T extends object | undefined>(
obj: T
): T | undefined {
const snap = useSnapshot(obj || proxy({})) as T;
return obj ? snap : undefined;
}or maybe this is more efficient? function useTempProxy<T extends object>(obj: T) {
return useMemo(() => proxy(obj), []);
}
export function useSnapshotAcceptUndefined<T extends object | undefined>(
obj: T
): T | undefined {
const temp = useTempProxy({});
const snap = useSnapshot(obj || temp) as T;
return obj ? snap : undefined;
} |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 1 reply
-
|
Yeah, it looks good. useMemo or something is required for stable reference. |
Beta Was this translation helpful? Give feedback.
-
|
@dai-shi would it make sense to support here a small example - I feel like it would make things easier // store.ts
interface MyObject = {
id: string
age: number
}
const elements = new Map<string, MyObject>([proxy({'a', 54}), proxy({'b', 23}), proxy({'c', 83})])
const selectedPerson = proxy({id: undefined})
// app.tsx
function App() {
const selectedPersonSnap = useSnapshot(selectedPerson);
// invalid but I think it's a valid approach in general
// const p = useSnapshot(objectStore.get(selectedPerson?.id || ''))
return (
<>
<p>
Selected Person:{' '}
{selectedPersonSnap?.id === undefined ? 'none' : selectedPersonSnap.id}
</p>
{selectedPersonSnap?.id && <SelectedPerson id={selectedPersonSnap.id} />}
<button type="button" onClick={() => (selectedPerson.id = 'a')}>
Select a
</button>
<button type="button" onClick={() => (selectedPerson.id = 'b')}>
Select b
</button>
<button type="button" onClick={() => (selectedPerson.id = 'c')}>
Select c
</button>
<button type="button" onClick={() => (selectedPerson.id = undefined)}>
unselect
</button>
</>
);
}
function SelectedPerson({ id }: { id: string }) {
const selectedPerson = useProxy(objectStore.get(id) || {});
return (
<>
// linter complains as id and name are no properties of {}
<p>{selectedPerson.id}</p>
<p>{selectedPerson.name}</p>
</>
);
} |
Beta Was this translation helpful? Give feedback.
Yeah, it looks good. useMemo or something is required for stable reference.