aribouius / jsonapi-react

A minimal JSON:API client and React hooks for fetching, updating, and caching remote data.
MIT License
149 stars 28 forks source link

SSR with Next.js #14

Closed etiennecl closed 3 years ago

etiennecl commented 4 years ago

This looks really great and I will definitely look a bit more into this. I was just wondering if you guys could provide an example using SSR with Next.js and if this library has been used in production?

aribouius commented 4 years ago

Hi @etiennecl,

I haven't used Next.js in a few years but I'm vaguely familiar with it. It doesn't look like this library is fully compatible with Next at the moment, but a few tweaks could get it there.

Per their docs, we would need to execute a request inside a getServerSideProps function .

import { ApiClient } from 'jsonapi-react'

export async function getServerSideProps(context) {
  const client = new ApiClient({ ... })

  const result = await client.fetch('todos')

  return {
    props: { result },
  }
}

From what I can tell you can't inject custom values into the context param, which means you'll need to create a new client instance for each getServerSideProps invocation. This is because the client instance currently stores each API response in its cache (regardless of cacheTime) to support client hydration, so creating an instance outside the method could result in a memory leak if you execute a large number of unique queries. This is an annoying limitation, but something I can probably provide a better solution for in the future (e.g. allowing the cache to be disabled when hydration is handled by a different library).

The next step would be setting up the component to handle the server-fetched data. This is actually where this library is currently missing a feature required for this to work.

import { useQuery } from 'jsonapi-react'

function Todos(props) {
   const { data } = useQuery('todos', { initialData: props.result })
}

The above example receives the server-fetched data as a prop, and passes it as initial data to the hook...the problem is useQuery doesn't currently recognize a initialData option. However it would be very easy to add :)

Let me know if this approach would work for you, I'd be happy to implement.

I can't say how many sites use this library in production, probably not many at this point. I started creating it for my company ~7 months ago as part of a big rewrite spanning 4 large apps. We are still a few weeks away from deploying them to prod, but so far it has endured a couple months of rigorous QA without problem. It is technically still in beta, but I don't foresee any major changes before we release the first major version.

etiennecl commented 4 years ago

Hi @aribouius,

First of all thanks for your well-explained response!

Indeed the getServerSideProps would need to be used in order to fetch server-side data. I could help in providing the client hydration options, but for the time being, initializing the client inside the getServerSideProps seems reasonable to me.

As for the initial data option, this is would be critical in order for us to use this library, I could also jump in if you need help!

aribouius commented 4 years ago

Hey @etiennecl,

I have added a initialData option to the useQuery hook (commit).

I'm holding off on updating the readme until i've had a chance to test it a bit more thoroughly. Let me know if this winds up working for you!

Steffi3rd commented 3 years ago

Hello @aribouius,

I tried the option initialData, it's undefined in my case 😢

https://github.com/aribouius/jsonapi-react/issues/32

farouk46015 commented 2 years ago

hey we have to define ApiClient in each request by getServerSiderProps

so we cant wrap app by ApiProvider