Closed BatuhanTopcu closed 1 week ago
Hey, thanks for your contribution!
Is it ok for me to ask some questions? I'm not sure I understand. Can you give me a code snippet example that doesn't work with the current API that will work if there is a getServerSnapshot
option?
I'm just trying to imagine your codebase and I can't. For example, I guess I will write the following code if I will need to do what I understand you are describing:
const [showModal, setShowModal] = useLocalStorageState('show-modal', {
defaultValue: false
})
if (!showModal) {
return null
}
return <div>modal</div>
How should I change the example below so it now needs a new option in order to work property (or you can just show a different example, if that's easier)?
Thanks in advance!
Also, I see two people liked the PR — @kadirgombel and @damla.
Do you have the same use case as well? Can you explain your need for such a property?
Thanks!
Hello, they are my coleagues.
Example:
const showWelcomeModal, setShowWelcomeModal] = useLocalStorageState('welcome-modal', {
defaultValue: true // we want to show welcome if value does not exist in local storage
})
if (!showModal) {
return null
}
return <div>welcome</div>
code below has an issue server always shows modal with SSR response but if welcome-modal
exists in local storage when client takes over it hides modal. so when I tried to change default value on defaultValue
based on environment it fixes that but then throws hydration error.
Thank you!
Sorry, I still don't understand. I will try to break this down and give you a CodeSandbox that you can edit so we are on the same page.
Can you edit this CodeSandbox so you make the modal div flicker?
Also, do you know that you can conditionally give a different defaultValue
as you tried but using useSyncExternalStore()
hook?:
const isServerOrHydrating = useSyncExternalStore(
() => {
return () => {};
},
() => false,
() => true
);
const [showWelcomeModal, setShowWelcomeModal] = useLocalStorageState('welcome-modal', {
defaultValue() {
if (isServerOrHydrating) {
return "server default value";
}
return "client default value";
},
})
I hope you understand me. I want to understand it before merging it.
Hello, yep there is no problem. https://codesandbox.io/p/devbox/suspicious-meninsky-forked-qf2pgw I added two cases:
1) User saw onboarding modal before, so shouldn't be saw it again
If I set defaultValue: false
and user's first enter, its written to localStorage
in getSnapshot
side of this lib so user can't see modal at all.
If I set defaultValue: true
and if user entered before, modal is rendered on server then removed from client (Flicker issue I meant)
2) I did not know isServerOrHydrating
hack you said It looked promised but has the same issue
const [showWelcomeModal] = useLocalStorageState("case-2", {
defaultValue: () => {
if (isServerOrHydrating) return false;
return true;
},
});
this will work in users recurrent enters to page without flicker so it is fixing that issue.
but in the first entrance defaultValue: false
written to localStorage while hydration so user not see modal at all.
I tried to simulate these states with
useLayoutEffect
but not sure that works, you can remove them and set local storage by yourself
I hope it was understandable; thanks for your time.
Nice! I think I got it.
So what you are trying to accomplish is this — https://codesandbox.io/p/devbox/suspicious-meninsky-forked-yz8zfr?workspaceId=d4f0087a-bf2e-4c09-a4d6-c87fd0d77ed8, right?
The example shows how to show the modal but not render it on server or while hydrating to avoid flicker and hydration errors. If you manually call localStorage.setItem('show-welcome-modal
, 'false')`, this will still not render the modal on the server or while hydrating and won't show it on the client as well.
That's it right?
Hello again,
I can't access the codesandbox but you are right, If I use
const [showWelcomeModal] = useLocalStorageState("case-2", {
defaultValue: () => {
if (isServerOrHydrating) return false;
return true;
},
});
there will be no flicker and hydration error but issue with this is defaultValue
sets given value to localStorage so user can't see the modal at all
Sorry, here's the link again, it should work now — https://codesandbox.io/p/devbox/suspicious-meninsky-forked-yz8zfr?workspaceId=d4f0087a-bf2e-4c09-a4d6-c87fd0d77ed8.
yep it's what I accomplish thank you! so should I use this hackish solution or can we merge this PR? thanks a lot!
I'll merge the PR. After I took the time to understand it, it seems like a good idea.
Thanks for your contribution!
I will try to make a release soon.
Thanks a lot for spending your time, This is my first contribution to open-source, and that felt awesome!
The release is ready.
It was fun for me as well! Your first contribution is really well done, keep the good work!
Reason
we have a modal to defaults to open if local storage value does not exists. If value for opened before is undefined we want to open modal. using
defaultValue
to set key tofalse
causes modal to flashes on top that. we tried setting different values for client and server indefaultValue
using it as function.code above prevents modal first opening then closing as flash but now causes hydration errors. fix is using
getServerSnapshot
to differ client and server defaults.getServerSnapshot
function runs during SSR and first hydration so it prevents that errors. See docsWhat is done
defaultServerValue
readme