Reputation: 172
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
Reputation: 482
Yep, you're taking extra steps in vain. Basically, you have 2 main approaches.
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}
/>
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