Skip to content
New issue

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

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

Already on GitHub? # to your account

RTK Query 2.0 Migration: Typing onQueryStarted without LifecycleApi types #4711

Open
JacobJaffe opened this issue Nov 12, 2024 · 1 comment · May be fixed by #4713
Open

RTK Query 2.0 Migration: Typing onQueryStarted without LifecycleApi types #4711

JacobJaffe opened this issue Nov 12, 2024 · 1 comment · May be fixed by #4713

Comments

@JacobJaffe
Copy link

I'm working on migrating a codebase to RTK 2.0.

I frequently have a pattern where I manually update the cache. I have been doing this via the lifecycle of onQueryStarted as recommended in #2864. My slices looks something like this, greatly simplified:

export const usersApi = rtkQueryApiSlice.injectEndpoints({
  endpoints: (builder) => ({
    getUser: builder.query<User, void>({
      query: () => ({ name: "get-user" })
    }),
    setFoo: builder.mutation<User, string>({
     query: (payload)  => ({ name: "set-user-foo", payload }),
     onQueryStarted: updateUserOnComplete
    }),
    performBar: builder.mutation<User, string>({
     query: (payload)  => ({ name: "perform-bar", payload }),
     onQueryStarted: updateUserOnComplete
    }),
})

I've had those re-used onQueryStarted functions defined like this:

import {
  MutationLifecycleApi,
  QueryLifecycleApi,
} from "@reduxjs/toolkit/dist/query/endpointDefinitions";

const updateUserOnComplete = async (
  arg: unknown,
  {
    dispatch,
    queryFulfilled,
  }:
    | MutationLifecycleApi<unknown, BaseQueryFn, User>
    | QueryLifecycleApi<unknown, BaseQueryFn, User>
) => {
  const res = await queryFulfilled;
  dispatch(
    usersApi.util.updateQueryData("get-user", undefined, (draft) => {
      if (draft?.id === res.data.id) {
        return res.data;
      }
    })
  );
};

As discussed in #4554 , this type-hack isn't available any longer. What's the proper way to type this re-used onQueryStarted function? I've tried drilling into how the type is made from the Lifecycle:

 {
    dispatch: ThunkDispatch<unknown, unknown, UnknownAction>;
    queryFulfilled: Promise<{
      data: User;
    }>;
  }

But this has a type error when attempting to dispatch the action. I'm confused about that, since it seems like that's the type that dispatch has when declaring onQueryStarted inline within the query definition.

Or maybe there's just a better way to be creating a reusable pattern here?

Any help would be appreciated.

@markerikson
Copy link
Collaborator

Yeah, we probably need to export more Typed* wrapper types here for this use case like we've done in other cases.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
2 participants