vikejs / vike-react

🔨 React integration for Vike
https://vike.dev/vike-react
MIT License
94 stars 15 forks source link

Ability to run code before hydration #110

Closed crisberrios closed 4 months ago

crisberrios commented 4 months ago

Currently, we have access to data and onBeforeRender on the SSR pass, but we don't have a way to execute code before the hydration pass. This limits the ability to hydrate stores and forces us to do additional render passes.

example:

onBeforeRender(pageContext) {

const { data } = pageContext;
let initialStore = createStore(initialData);

if (!pageContext.isClientSideNavigation) {
     hydrateStore(mapData(data));

    return {
      initialStore: serializeStore(initialStore)
    }
  }
}

Then on the client side:

function Page() {
  const { initialStore, isHydration } = usePageContext()

  if(isHydration) {
    hydrateStore(store, initialStore)
  }

  return (
    <>
    {store.someValue}
    </>
   )
 } 

Ideally, the store would be already hydrated before the hydration pass. This could be achieved by adding a custom hook such as +onBeforeHydration.

For my use case, making this a simple hook with a signature like `(pageContext) => void) would suffice, but for ergonomics, I think this could/should also work as a middleware, support async, and return pageContext.

For my example, this would look like:

import { store } from '../stores/store';
onBeforeHydration(pageContext) {
  hydrateStore(store, pageContext.initialStore)
}

and an async use case

async onBeforeHydration(pageContext) {
  const asyncData = await someAsyncPreRenderFunction();
  return {
     someProp: asyncData
   }
}

This would be similar, if not the same as #96

It may also help solve #87 and #57.

brillout commented 4 months ago

How about onBeforeRenderClient()? (Note pageContext.isHydration.)

PR welcome, but I can also do it once I'm done with the head management redesign.

crisberrios commented 4 months ago

That works, I'll give it a shot, thank you.

brillout commented 4 months ago

Pre-released as 0.4.8-commit-68be831