Update other slice after request
Asked Answered
E

2

5

using RTK Query, how can one use the fetching functionality to update another the state of another slice?

Essentially I'm trying to keep all related-state next to each other, and thus after querying data with the useLazyGetQuery, I'd like to use the result and store it in an existing slices state.

Whilst something like the below works from an component, it makes the whole code messy

  const [trigger, result, lastArg] = useLazyGetFiltersQuery();

  React.useEffect(() => {
    if (result.status === 'fulfilled' && result.isSuccess === true && result.isLoading === false) {
      dispatch(updateData(result.data.map((pg) => ({ label: pg, value: pg }))));
    }
  }, [dispatch, result, result.isLoading, result.isSuccess, result.status]);

I'd rather want to setup some logic directly in the createApi method so that the resulting data is stored from the beginning in the slice I want.

Thanks

Expander answered 8/8, 2021 at 18:33 Comment(0)
U
7

Generally, I would advise against copying data out of RTK-Query unless you have a very good reason: you will have to hand-write a lot of stuff, pretty much defeating the purpose of RTK-Query and you lose stuff like automatic cache collection of unused cache entries - from that point on you have to do that yourself.
Also, that data is already in Redux. Usually, you should not duplicate data in the store when you can avoid it.

That said, of course you can do it. For example, it is shown in the "Using extraReducers" authentication example:

const slice = createSlice({
  name: 'auth',
  initialState: { user: null, token: null } as AuthState,
  reducers: {},
  extraReducers: (builder) => {
    builder.addMatcher(
      api.endpoints.login.matchFulfilled,
      (state, { payload }) => {
        state.token = payload.token
        state.user = payload.user
      }
    )
  },
})

Keep in mind: this is Redux and everything happens via actions. You will never have to useEffect something to write it back into state. Just listen for the right actions in your reducers.

Uterus answered 8/8, 2021 at 20:1 Comment(8)
If we simply don't plug the reducer generated by createApi onto our store, and only use matcher to catch those async actions, that would avoid duplicated data in our store ?Angelenaangeleno
@Angelenaangeleno Theat would render the middleware useless, since that relies on that state quite a lot. So in the end you would be left with only the thunks for data fetching and tbh, even those might need some of that reducer data. But even if it would work, you would have disabled about 90% of RTK-Query.Uterus
how do you handle data which you got with rtk query but you need to add some local UI property, something like visible: false and then this property update you only need on client side so you dont want to make mutationBrakesman
@LevanGulisashvili as it is not "server data", I'd keep it completely separate.Uterus
for example if you have some array which contains objects. for example imagine folder tree , at first what i want is to all folders be collapsed but when you click on them they should toggle and this have to be saved in localstorage as well so it will persist across refershs.... so what is your solution here? to create local state with folder ids ? which will have boolean value ? and then where i am rendering all this folders map visibility ?Brakesman
@LevanGulisashvili Another Redux state that contains only the additional data. What do you gain from copying the API data and the additional data in there, apart from a risk of things going async?Uterus
no i only copy id's so i can know which folder is visible which is not based on id ... otherwise how can i identify ?Brakesman
for example if i have folder obj like { name: "folder1", id: 32 } i have to create local state { 32: false } that way i can know that this folder has to be collapsed ...Brakesman
E
0

I know it's too late but hope someone get benefit from it

  const { isSuccess, data, isLoading } = alwaysRunQuery();
  const { data:myData } = conditionalQuery(undefined, {
    skip: !isSuccess,
  });
Ethelda answered 27/6, 2023 at 9:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.