Next.js Discord

Discord Forum

How can I make a client component (which needs to be server rendered) later unmount itself

Unanswered
୧ʕ•̀ᴥ•́ʔ୨ posted this in #help-forum
Open in Discord
I have this overlay component which, only in the browser, and under a certain condition needs to unmount itself. But the code below doesn't work:

'use client'

export default function Overlay() {
    const inBrowser = typeof window !== 'undefined'
    const hasSpecialValue = inBrowser && localStorage.getItem('special-value')

    if (hasSpecialValue) {
        return null
    }

    return <p>This message needs to be server rendered and only removed on the client if special value is found in local storage.</p>
}

I can't use a dynamic import because it causes a flash of content before the message appears when the value isn't in local storage. What would be a good solution to this?

29 Replies

I have an overlay that appears over the page by default, unless you're a special type of user and in your local storage you have this value, in which case the overlay needs to disappear. The important thing is that flash of the page isn't acceptable for normal users (who will see the overlay appear), whereas flash of the message which then disappears is acceptable for the "special" users
Or ideally there wouldn't be a flash at all, but it's only a requirement that normal users don't see one
@୧ʕ•̀ᴥ•́ʔ୨ Or ideally there wouldn't be a flash at all, but it's only a requirement that normal users don't see one
So if I understand you right, you want to have a overlay if a user is allowed to see this overlay (if value is in localstorage) and if not, the user should see the overlay. There should be no flash
Correct?
It's the opposite, overlay is there by default for everyone, but will disappear (with a delay/flash is fine) if you happen to have the value in localstorage
Yes, correct
Well, that’s a problem. Because the overlay should be directly visible. But it won’t, because the client need to load it first. And that happens only after the server side content has rendered. So add it to your serverside content so it will be showed instantly and will then be either hidden or not
Uh sure, but how do I hide it later?
@୧ʕ•̀ᴥ•́ʔ୨ Uh sure, but how do I hide it later?
The client component „Overlay“ (or however you called it) will be rendered and that component checks the condition, that you need and hides itself when the condition is met or it stays visible
I tried that (see the code example at the start), but apparently you can't return different values on the client than on the server.
So I can't check the condition and return null or false from the component on the client
Ideally I'd want the component to unmount itself as it's not needed
@୧ʕ•̀ᴥ•́ʔ୨ I tried that (see the code example at the start), but apparently you can't return different values on the client than on the server.
The client component can still conditionally render. So if the condition is met, return null and if not display the overlay (if not is the default)
You mean in the parent? The parent is a server component, so it can't access local storage
This code doesn't work though
The overlay doesn't disappear on the client
If I try to return anything different I get a hydration error, if I return null or false, it simply does nothing (it stays as it is)
Thanks for setting that up. I wanted to avoid the flash of content on page load, the overlay should be there by default, this is why I was avoiding using dynamic()
Is the flash only in dev mode then? When I press refresh on the codesandbox, I see the buttons first, and then the overlay appears and pushes them down
Well the overlay is meant to cover the content of the page, so I don't want there to be a flash of the page before the overlay appears
When I build it locally and run it with npm run start, there's a bit of a flash of the underlying content before the overlay shows up
Thanks, that's a useful pointer, I'll take a look