Make useStore compatible with client-side hydration of SSR components#10
Make useStore compatible with client-side hydration of SSR components#10ai merged 6 commits intonanostores:mainfrom
Conversation
…t-side hydration is complete When a value is provided for the new optional `initial` option, that value is returned by `useStore` instead of the store's current value until hydration is completed on the client, as detected by completion of the first-run `useEffect`. This `initial` option avoids hydration errors on projects that use Server Side Rendering (SSR) combined with client-side navigation and rendering, where the client-side store value can get out of sync with the value in the server-rendered page especially if the server page is cached in any way (ISR).
|
This change currently increases the package size by 30 bytes to And if this approach of adding an |
|
30 bytes is not a so big problem. I do not like the idea of duplicating initial value, it looks like a hack which lead to duplication. Also, as I know React has the same issue. Maybe we can add |
|
Thanks for the feedback. And yes, I agree having to pass in Keeping the initial value in the store itself then referring to it in the My only concern with using a |
…al value Make the store's initial value available via the `init` attribute. This is intended mainly for internal use by integrations like React and Preact that need to return the initial value during the rendering lifecycle. See: - nanostores/preact#10 - nanostores/react#38
…al value (#390) * Add `Store#init` low-level attribute to always return a store's initial value Make the store's initial value available via the `init` attribute. This is intended mainly for internal use by integrations like React and Preact that need to return the initial value during the rendering lifecycle. See: - nanostores/preact#10 - nanostores/react#38 * Add tests for `Store#init` attribute, and increase size limit to 270b / 804b for Atom / Popular respectively * Improve tests for map to ensure `setKey` doesn't change value of `init`
This requires an upcoming release of nanostores including the new `Store#init` attribute from PR: nanostores/nanostores#390
|
NOTE: Tests are expected to fail for recent updates to this PR until |
initial option to fix hydration errors with SSR pagesI haven't found a way to detect hydration errors when a component with updated state data is hydrated over "server" rendered markup, but this change brings the tests closer to the related tests in nanostores/react which better demonstrate the original problem and the fact this PR solves it.
|
@jmurty can you provide some arguments why we always should use initial data on the server? On React we follow their official API. But here seems like we are adding extra layer of unexpected complexity. For instance, I can assume that some users can use Also, am I right that on the client-side first it will be rendered with initial value, then |
|
Hi @ai you're right that always returning the initial data is a change in behaviour and potentially a breaking change. It's following the React way of doing things, but this isn't necessarily the also right way for Preact. I worried about this in an earlier comment, but not clearly. I think we shouldn't always use initial data for the Preact hook, on server-side or on client-side. And I hadn't even thought of the case for server-only rendering where We should probably make users opt-in to the new SSR behaviour. Perhaps add an |
Hi, please consider improving support for projects that use SSR / ISR pages with client-side navigation, which can currently get hydration errors without a work-around like this.
Add
initialoption to return same value as used for SSR until client-side hydration is completeWhen a value is provided for the new optional
initialoption, that value is returned byuseStoreinstead of the store's current value until hydration is completed on the client, as detected by completion of the first-runuseEffect.This
initialoption avoids hydration errors on projects that use Server Side Rendering (SSR) combined with client-side navigation and rendering, where the client-side store value can get out of sync with the value in the server-rendered page especially if the server page is cached in any way (ISR).