- Published on
The Case for Redux Toolkit Query
- Authors
- Name
- Charlie Maloney
About 6 months ago, our team decided to migrate our existing redux logic to redux toolkit. Like many other developers, we found that the "old" way of writing redux logic was becoming too cumbersome. Even with the abstractions that redux hooks provide, our application logic felt bloated.
In general, we tend to prefer using React's useState
and Context
APIs for most of our state needs and found that a majority of our redux logic concerned fetching data from our server. For our async logic, we followed a pretty standard redux thunk pattern:
// sets loading flag to true
export const fetchData = () => ({
type: FETCH_DATA,
});
// sets loading flag to false & stores data in redux store
export const fetchDataSuccess = (payload) => ({
type: FETCH_DATA_SUCCESS,
payload,
});
// sets loading flag to false & sets error message in redux store
export const fetchDataError = (error) => ({
type: FETCH_DATA_ERROR,
error,
});
// the function that ties it all together
export const fetchDataAction = () => async (dispatch) => {
dispatch(fetchData());
try {
const data = await axios.get('/data'));
return dispatch(fetchDataSuccess(data));
} catch (error) {
return dispatch(fetchDataError(error));
}
};
Even without considering the logic in the reducer and the consuming react component, we can see from this small, contrived example, there is a TON of boilerplate code just to fetch some data from the server.
For 90% of data fetching from the frontend, we typically need just three things:
- the loading state
- the error state
- the data
Enter Redux Toolkit Query. Quoting from their docs:
RTK Query is a powerful data fetching and caching tool. It is designed to simplify common cases for loading data in a web application, eliminating the need to hand-write data fetching & caching logic yourself.
Thanks to the team at RTKQ, all of this logic can be encapsulated into just a single hook:
const { data, isLoading, error } = useDataQuery()
Here's how it looks in the context of the component:
export const Component = () => {
const { data, isLoading, error } = useDataQuery()
if (error) {
// handle error
}
if (isLoading) {
// display loader
}
return (
<>
{data.map({* display data *})}
</>
)
}
For our data fetching needs, RTKQ has been a life saver. What used to span multiple lines of code over many different files has been reduced to just one function call.
However, this is just the tip of the iceberg. RTKQ comes with other functionality such as:
- caching
- refetching
- easy cache invalidation
- mutations
- polling
With all of these amazing features, it's no wonder that libraries like RTKQ and react-query are growing in popularity.