[Proposal] context #1544
-
Hey, First off, I love this library. Jotai is easily a DX improvement on par with hooks. However, initializing atoms from the React tree is messy and difficult (#1113). Why?Currently the only way to initialize atoms on render is with a
Currently: const userIdAtom = atom('');
const userDataAtom = atom(
get => fetch(`/user/${get(userIdAtom)}`).then(res => res.json())
);
function UserPage() {
const { id } = useParams();
return (
<Provider initialValues={[[userIdAtom, id]]} key={id}>
</Provider>
)
} ProposalProvide With const userIdAtom = context<string>();
const userDataAtom = atom(
get => fetch(`/user/${get(userIdAtom)}`).then(res => res.json())
);
function UserPage() {
const { id } = useParams();
const UserID = useAtomContext(userIdAtom);
return (
<UserID value={id}>
</UserID>
);
} Accessing the context atom outside of its descendants could throw. Exampletype Context = { id: string };
const appContextAtom = context<Context>();
function App({ context }) {
const AppContext = useAtomContext(appContextAtom);
return (
<AppContext value={context}>
<Routes>
<Route path="/user/:id" element={<UserPage />} />
</Routes>
</AppContext>
);
}
const userIdAtom = context<string>();
const userFriendsAtom = atom(
get => fetch(`/user/${get(userIdAtom)}/friends`).then(res => res.json())
);
const userIsMyFriend = atom(
get => {
const me = get(appContextAtom).id:
const userFriends = get(userFriendsAtom);
return userFriends.includes(me);
}
);
function UserPage() {
const { id } = useParams();
const UserID = useAtomContext(userIdAtom);
return (
<UserID value={id}>
<UserRelationship />
</UserID>
)
}
function UserRelationship() {
const userIsMyFriend = useAtomValue(userIsMyFriendAtom);
return userIsMyFriend ? 'You are their friend' : 'You are not their friend';
} Notes
const genericContextAtom = context();
function App({ context }) {
const GenericContext = useAtomContext();
return <GenericContext value={context} />
}
const [genericContextAtom, GenericContext] = context();
function App({ context }) {
return <GenericContext value={context} />
}
const genericContextAtom = context();
function App({ context }) {
return <genericContextAtom.Provider value={context} />
} |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
Yes, we misguided the use of I think what you propose is covered by jotai-molecules. If so, what we should do is to write docs about it and recommend using it. From the API surface, your proposal looks a little different though. I like the idea of making an atom contextual. Although, we can't implement the proposed api without breaking some of React rules. (Otherwise, we could have made |
Beta Was this translation helpful? Give feedback.
Yes, we misguided the use of
Provider
for initializing atom values from props. That doesn't work well for typical cases.useHydrateAtoms
were to rescue, but it can only set values for uninitialized atoms, which doesn't cover all cases.I think what you propose is covered by jotai-molecules. If so, what we should do is to write docs about it and recommend using it.
From the API surface, your proposal looks a little different though. I like the idea of making an atom contextual. Although, we can't implement the proposed api without breaking some of React rules. (Otherwise, we could have made
useHydrateAtoms
to update already initialized atoms.)