magrega
magrega

Reputation: 172

Get data straight from query hook regardless of params sent

I have a table where all of the fetched data renders and I have different components that make api calls with different args (filters). How can I use query hooks to get any fetched data to render in that table regardless of parameters sent?

Now I am storing fetched data to a variable in global store and access it in the table with useSelector but I think there are some steps that could be avoided since I am double storing fetched data. (One comes with query, second I store manually with dispatch()).

Here's the example: Here I get data from api and destructure refetch function to trigger fetch if query parameters change. Parameters are stored in Redux store.

const query = useSelector((state) => state.orderList.queryParams);

  const { refetch } = useGetOrderListQuery(query);

  useEffect(() => {
    refetch(query);
  }, [query, refetch]);

This hook is used in table component to show whether loading is happening const { isFetching } = useGetOrderListQuery(query);

As you can see I don't use data from query hooks. I set data manually inside useGetOrderListQuery.

getOrderList: builder.query({
      query: (arg) => ({
        url: ORDER_LIST,
        params: { ...arg },
      }),
      providesTags: ["Orders"],
      async onQueryStarted(_, { dispatch, queryFulfilled }) {
        try {
    const { data } = await queryFulfilled;
    console.log(data);
    dispatch(setOrderData(data.results));
  } catch (err) {
    console.log(err);
  }
      },
    }),

I believe I can avoid doing this dispatch(setOrderData(data.results)); and access data right from the query but I don't see how.

Right now I am storing fetched data in the redux store but I think I can avoid it and get data from the query itsekf every time api call is made. The problem is that sometimes I need to pass different arg to query and I won't be able to get the same data.

Upvotes: 0

Views: 147

Answers (1)

Brogrammer
Brogrammer

Reputation: 482

Yep, you're taking extra steps in vain. Basically, you have 2 main approaches.

- Hooks

You can access the data directly from the hook:

OrdersScreen.tsx

const filters = useAppSelector(selectOrderFilters);

const { data: orderList, isLoading, refetch } = useGetOrderListQuery(filters, { 
  refetchOnMountOrArgChange: true 
});

<Flatlist 
  data={orderList}
  keyExtractor={(item) => String(item?.id)}
  renderItem={renderItem}
/>

- Selectors

In case you want to access the data directly from Redux and also w/o hooks you don't need to create a new Slice instead you can create custom selectors to access the cached data.
Let's say your apiSlice is called ordersApiSlice:

export const selectOrders = (state: RootState) => ordersApiSlice.endpoints.getOrderList.select(store.orderList.queryParams)(state);

// Usage: 
const orders = useAppSelector(selectOrders);

If you have to manage data before consuming it or something like that take in mind using createSelector().

Upvotes: 1

Related Questions