-
-
Notifications
You must be signed in to change notification settings - Fork 642
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature: useHydrateAtoms #637
Conversation
This pull request is being automatically deployed with Vercel (learn more). 🔍 Inspect: https://vercel.com/pmndrs/jotai/7Lr547M83ZgxbPh4ynTY55XsKHxZ |
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. Latest deployment of this branch, based on commit baece10:
|
@Thisen looks good I have a couple questions, which I think are essentially the same. If two components both use |
The current implementation is: Do you see any issues with this? |
Yes. So, for @Nazzanuk 's use case in #340 (comment), useEffect is still required. |
Yup. We might need a better mechanism. |
I think it's ok to run only once on the first render, the value will come directly from the atom afterwards anyway, so updating can be handled in a useEffect. Just thinking about my scenario, I'd only want the atom to be updated once / or maybe only if the value is nullish. I'd be hesitant to use the current hook in a deeper component with wider reuse as I may not be sure of which instance will render first/last I could be thinking of a different scenario from what was intended, I still have this in mind. |
I also think it's ok. useEffect on user end seems like a valid use case.
Could you elaborate your concern? I almost understand what this means, but would like to have a better understanding. |
@Thisen I have one concern. If we restore atoms, atoms onMount won't fire... |
I think this is a bit contrived but it might help illustrate. const userIdAtom = atom<number | null>(null);
const MyUserWidget = ({ userId }) => {
useHydrateAtoms([[userIdAtom, userId]]); // what happens if userId is empty?
const [userId, setUserId] = useAtom(userIdAtom);
return <>...widget</>;
};
const App = () => <>
<Header/>
<Container>
<MyUserWidget userId={23}/>
<ChangeUserButton /> {/* Updates userIdAtom */}
<LazyComponent> {/* Rendered lazily or asynchronously */}
<MyUserWidget userId={23}/> {/* What should userId be here? Will it reset the first widget just by rendering? */}
</LazyComponent>
</Container>
<Footer/>
</>; Thinking of an example was quite difficult actually, and this can all be fixed by hoisting But is there a use case where an atom would need to be hydrated more than once? |
@Thisen My bad. If we use Oh, onMount would work even with Provider's initialValues. We fixed this probably in #353. |
@Nazzanuk I'm not quite sure how people would like to use it, but
I agree with this. My concern is that it's hard to detect misusage from the library, so we would need a good doc about the correct usage. |
Ah ok, yeah I think the current implementation works really well. It will make the integration with Next.js much cleaner and more straightforward. If needed I can wrap it in another hook for my particular use case (check first if nullish). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great. Thanks for your work!
Adds a new hook, that can hydrate an atom with a initial value.
Primary use case is SSR/Next.js, but it's not bound to anything.
Please supply your use cases, so we can experiment/test this hook properly.