Closed nitedani closed 2 years ago
Hey @nitedani, this is the new setup for hydration with the Blitz Toolkit: https://canary.blitzjs.com/docs/query-usage#prefetching (we removed the boilerplate and you don't have to pass dehydratedState
explicitly). How does this look to you?
If this is what I think it is, it's good. How would I use this?
import { invoke } from "@blitzjs/rpc"
function ProjectPage(props) {
const project = await invoke(getProject, { where: { id: props.id } })
return <div>{project.name}</div>
}
Is it simple as that?
No, you'd still need getServerSideProps/getStaticProps, but we removed the prefetching boilerplate required:
import { gSSP } from "app/blitz-server"
import getProject from "app/projects/queries/getProject"
export const getServerSideProps = gSSP(async ({ ctx }) => {
await ctx.prefetchBlitzQuery(getProject, {
where: { id: context.params?.projectId },
})
return { props: {} }
})
function ProjectPage(props) {
const [project] = useQuery(getProject, { where: { id: props.id } })
return <div>{project.name}</div>
}
export default ProjectPage
It's not exactly what you mentioned in your issue, but it's much simpler than it used to be.
It is good that you removed some boilerplate. I don't want to sound peasant, but in my opinion this is still too repetitive code for the developers. I would need to jump in the code back and forth the prefetchBlitzQuery and useQuery. Today I read about react 18 Suspense here: https://github.com/reactwg/react-18/discussions/37. I like where they are going with that. Maybe it will make possible what now seems impossible 😄 I'll close this issue and experiment what's possible with suspense.
I found the way to do it how I like it 😄 This is using vite-plugin-ssr. I just had to enable suspense for react-query. The ctx.reactQueryState is transferred to the browser in the html, then loaded into react-query cache. Its just a proof of concept, but the future looks promising to me.
import { Suspense } from "react";
import { useQuery as _useQuery, useQueryClient, dehydrate } from "react-query";
import { usePageContext } from "../../renderer/usePageContext";
function useQuery<T>(
key: string,
queryFn: () => Promise<T>
): { data: T | undefined } {
const { data } = _useQuery(key, queryFn, { staleTime: 99999 });
if (import.meta.env.SSR) {
const queryClient = useQueryClient();
const ctx = usePageContext();
const dehydratedState = dehydrate(queryClient);
Object.assign(ctx.reactQueryState, dehydratedState);
}
return { data };
}
function Test() {
const { data } = useQuery("test", () =>
fetch("https://httpbin.org/get").then((res) => res.json())
);
return <div>{JSON.stringify(data)}</div>;
}
function App() {
return (
<div>
<Suspense fallback={<h1>Loading...</h1>}>
<Test />
</Suspense>
</div>
);
}
export { App };
What do you want and why?
I would like an alternative for getServerSideProps and getStaticProps. They are too much boilerplate. The dehydration/hydration should be centralized.
Right now it looks like this:
It would become this:
Just for comparsion, in nuxt3 it looks like this:
I would like blitz to go in the same direction and create a function something like:
On the server side, the response to the browser would be sent when all of the useAsyncData callbacks resolved. The transfer of state from server to browser would be handled by the framework.