Closed josharens closed 1 year ago
This is intentional. It's required to avoid hydration mismatches between what's rendered on the server and client, or React will emit warnings. So the first render will always match what was rendered on the server, and then update to the client rendering afterward.
Hey @devongovett, thanks for responding. So just to be clear, if my app has already hydrated, and then I render a new component using useIsSSR()
, it's expected that it should first return true
and then false
, instead of just returning false
?
Ah I understand what you mean. We could potentially keep track of that I guess using some global flag, but not exactly sure how we'd know when hydration is complete for all components...
not exactly sure how we'd know when hydration is complete for all components...
Previously I had a useEffect()
in my root <App>
component that would update a HydrationContext
when run, signaling that hydration had completed. This may be naive, but theoretically something similar could be done in SSRProvider.
I'm on React 17 currently, so I haven't put any thought into whether or not React 18 throws a wrench in that.
Yeah I think partial hydration/async rendering probably would make this harder.
Doing a little more digging into React 18's selective hydration, and I think for my current specific use case, using the new useSyncExternalStore hook (or the shim since I'm on React 17 at the moment) is a better solution than trying to track when hydration is complete myself.
I still think that the useIsSSR()
hook seems a little flawed, but I don't have a good solution. Perhaps the useSyncExternalStore()
hook will ultimately end up becoming the go-to for this sort of problem anyways.
π Bug Report
I may have misunderstood the useIsSSR() documentation, but it isn't working the way I would expect it to.
π€ Expected Behavior
The
useIsSSR()
hook should always returnfalse
after the app has hydrated on the client.π― Current Behavior
Currently, the hook always returns
true
(meaning the app is server side rendering, or hydrating) before flipping tofalse
every time it's mounted, even after hydration. I would expect it to always returnfalse
after hydration instead oftrue
and thenfalse
.π Possible Solution
No possible solution, but this line seems suspect to me. The
isSSR
state is always initiallytrue
, even if the app has already hydrated.π¦ Context
My use case involves using
useIsSSR()
to create a hook that returns the device's pixel ratio. On the server and during hydration this hook returns a default value. After hydration it should always returnwindow.devicePixelRatio
.π» Code Sample
This example is a bit contrived since there isn't any server side rendering happening, but it still illustrates the potential issue.
https://codesandbox.io/s/tender-violet-kunchu?file=/src/App.js
π Your Environment
@react-aria/ssr@3.2.0
Chrome
MacOS
π§’ Your Company/Team
SmugMug