Manage Asynchronous State in React with EASE
Tags: react, webdev, redux, reactquery
Published: 2021-04-22 04:55:05

Earlier when I started learning React I always turn to Redux w/ Thunk as my go to State Management specially when I'm trying to fetch asynchronous data. 

When doing my small projects I always start setting things up with the Redux `store.js`, the `reducers`, and `initialState`. A bit tedious setup but it is still tolerable, but when you find your self handling a few `GET` request here, a bit of `POST` request there and you a mass a collection of ACTION and REDUCER combo. 

> REDUCER is where you handle the state. And where we can keep track if our data is still "loading state" or something went wrong "error state" depends what our ACTION dispatched
```js
export const productListReducer = (state = { products: [] }, action) => {
  switch (action.type) {
    case PRODUCT_LIST_REQUEST:
      return { loading: true, products: [] }
    case PRODUCT_LIST_SUCCESS:
      return { loading: false, products: action.payload }
    case PRODUCT_LIST_FAIL:
      return { loading: false, error: action.payload }
    default:
      return state
  }
}
```

> ACTION usually an asynchronous function where you handle your "business logic" and dispatch. Your data fetch inside a try catch block so you can also catch errors
```js
export const listProducts = () => async (dispatch) => {
  try {
    dispatch({ type: PRODUCT_LIST_REQUEST })
    const { data } = await axios.get('/api/products')
    dispatch({ type: PRODUCT_LIST_SUCCESS, payload: data })
  } catch (error) {
    dispatch({
      type: PRODUCT_LIST_FAIL,
      payload:
        error.respose && error.respose.data.message
          ? error.response.data.message
          : error.message,
    })
  }
}
``` 

### React Query 

This past few months of my learning journey, a fetching library in react have been repeatedly came up, especially when I started hacking into Next.js, it's either React Query or SWR cause they are quite similar. 

So my curiosity got the best of me! Tossed a coined and checked out React Query. It's super simple but complex library that can eradicate lines of code! 

So this is how a simple fetch looks with React Query's provided hook `useQuery`. 

> The first argument is a unique key and the second is the fetcher function.
```react
 const { isLoading, error, data } = useQuery('products', () =>
     fetch('https://api.shopping').then(res => res.json())
   )
```
> Pro Tip: You can make a custom hook using these so you won't have to write the whole thing every time you use it.

With this hook we can track our loading state, catch errors, and get our data. We just snapped all the boiler plate code that we had to do using Redux out of this universe. 
![Snap](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1t0q6o0ffwmguj7ubbuk.gif)

Not only that, one of the major benefit of using a server-state library like React Query is caching your fetched data. 

The first argument on `useQuery` hook is a unique key used to name the cached data. So when your app runs a hook query it checks the cache for the key, if it already exists it will serve you the stored data instantly without fetching it again.

### Conclusion 
There is a lot more concepts and mind blowing stuff you can do with this library. You can even use this as your GraphQL client instead of Apollo. 

But for now I just want you to be aware of this awesome tech. Pairing this with any Client State you prefer would elevate your projects' user experience!  

> And yes I'am aware of Redux toolkit that removes alot of the overhead setup of an "Old school Redux" but it still not as efficient in handling asynchronous data.