Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RTKQ: How to fill endpoint cache on app start? #1366

Closed
MaximKondratev opened this issue Jul 30, 2021 · 5 comments
Closed

RTKQ: How to fill endpoint cache on app start? #1366

MaximKondratev opened this issue Jul 30, 2021 · 5 comments

Comments

@MaximKondratev
Copy link

In my app i create store based on some initial data, passed to client. If i have data I need to fill an endpoint cache on app start so it do no call endpoint when query run later with same arg.

const api = createApi({
    ...
    endpoints: (builder) => ({
        myEndpoint: builder.query({
             query: (id) => `myEp/${id}`,
        }),
    })
})

type AppInitialData = {
    prefilled: {
        id: number;
        data: SomeData;
    } | null
}

const createStore = (appInitialData: AppInitialData) => {
    const store = configureStore({
        reducer: {
            [api.reducerPath]: api.reducer,
        },
        middleware: (getDefaultMiddleware) => {
            return getDefaultMiddleware().concat(data.middleware);
        },
    });
    
    if (appInitialData.prefilled) {
        // fill myEndpoint cache for appInitialData.prefilled.id with appInitialData.prefilled.data
    }
    
   return store;
}

// later
// initialId is the same as prefilled.id in AppInitialData
const MyComponent = ({ initialId }) => {
    const [id, setId] = useState(initialId);
    // On first run query data is filled and do not produce call to an endpoint. User sees result immediately
    const query = useMyEndpointQuery(id);
    return ...
}

i tried to call updateQueryData right after configureStore

dispatch(api.util.updateQueryData('myEndpoint', prefilled.id, (draft) => {
    draft = prefilled.data;
}));

but it did nothing. i guess it is impossible to update a query that was not initiated.

so i tried to call initiate and then updateQueryData

dispatch(api.endpoints.myEndpoint.initiate(prefilled.id));
dispatch(api.util.updateQueryData('myEndpoint', prefilled.id, (draft) => {
    draft = prefilled.data
}))

but initiate call produces request that i dont need. updateQueryData still does nothing, i guess because query is in pending state.

Is there any way to achieve this behavior? Or did i miss something?

@phryneas
Copy link
Member

The next version of RTK will have hydration functionality, you can already try out the experiment in #1277 but it is at the moment a work in progress.

If you use the CodeSandbox build from there, here's some usage info:

It works by writing a extractRehydrationInfo method like here that would extract the slice state from a hydration action as used by redux-persist or next-redux-wrapper
https://github.com/phryneas/ssr-experiments/blob/126262fcce7f8b788df3670dbc061362c65b6b9e/nextjs-blog/lib/pokemonApi.ts#L8-L12

Alternatively you can also dispatch(api.internalActions.rehydrate(apiSliceContents))

@MaximKondratev
Copy link
Author

I think hydration will solve part of my problems, but not every. I still need a way to manually set data to api slice in some cases.

Let's imagine I have my api slice with myEndpoint endpoint. Most of time users will interact with it through useMyEndpoint() hook. But i also have a use case when i fetch anotherEndpoint and it returns some data, including the same data myEndpoint would get, but it is not only it. I want to fill myEndpoint cache when i get result from anotherEndpoint so i don't need to make duplicate request and wait it to finish

@TomasSestak
Copy link

This would be useful, for example when fetching in static props/server side props in Next.js

@phryneas
Copy link
Member

phryneas commented Oct 16, 2021

@TomasSestak for SSR we have #1277 coming up, including rehydration of data from the server on the client.

@markerikson
Copy link
Collaborator

I believe this is covered by the hydration functionality in 1.7.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants