-
Notifications
You must be signed in to change notification settings - Fork 125
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
storage: solve hydration issue #738
base: main
Are you sure you want to change the base?
Conversation
🦋 Changeset detectedLatest commit: b3a785b The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Why not use isHydrated (or it's implementation directly since it's just some "is hydrating" checks and onMount) in the primitive by default? if (!isServer && sharedConfig.context) {/*delay init*/}
else {/*init immediately*/} This is what all the primitives what read something from the dom like |
We do not know if the server and the client will have access to the same data on their storage. You could also using the sync API or cookieStorage to keep them in sync, so I do not want to make it a default, because then the delayed initialization on the client could introduce hydration mismatches if the fallback is hydrated. |
Is there a way to ensure consistency automatically? |
If this is out of scope of this pr, and you just want to introduce a temporary fix, then I don't mind. makePersisted(init, {useInitDuringHydration: true}) As opposed to telling users to pull another dependency. |
There is no way for us to know on either server or client what data the other side will have unless we either sync them manually or deliberately let them be out of sync.
No, but one could also choose this to block initialization until any moment of your choice. |
OK, I switched to your suggested solution. |
looks good
If you think this valuable, |
The new And fyi, good idea in your example @thetarnav, but I don't think onMount returns a value (I'm not on the latest version though). We might want to keep isHydrated in the docs at least.. I'm making some assumptions here though I don't know all the details about the difference in onMount and isHydrated. function onMount(fn) {
createEffect(() => untrack(fn));
} |
No, isHydrated is pretty much onMount as a signal with a hydration check:
why would it return a value? currently the logic is: const initialize = () => {...}
if (options.deferInit) {
onMount(initialize)
} else {
initialize()
} and my idea would look something like this const initialize = () => {...}
if (options.deferInit) {
options.deferInit(initialize)
} else {
initialize()
} |
I was referring to this:
If onMount did return a value that would be useful. |
|
In order to simplify avoiding hydration issues, makePersisted now accepts
isHydrated
from the lifecycle package as an option to delay the initialization from storage until the parent is hydrated; since this way both server and client will have the same default on initial rendering, this will make them render the same, thus no longer causing hydration mismatch errors.Another solution would be to sync the storage with the server and use makePersisted on the server, too.
This addresses #737