Implementing Refresh Token in React Using Axios, Zustand, and React Query

Kiran Kumal
3 min readJun 17, 2024

--

Introduction

In modern web applications, managing user authentication is crucial in modern web applications, and handling token expiration seamlessly can significantly enhance user experience. This article will guide you through implementing a robust token refresh mechanism in a React application using:

  • Axios for HTTP requests and interceptors.
  • Zustand for state management and local storage persistence.
  • React Query for data fetching and caching.
  • React Hook Form and Zod for form state management and schema validation.

By the end of this article, you’ll know how to ensure a smooth and secure token management system in your React app. Let’s get started!

We’ll begin by initializing a new React app with TypeScript using Vite for rapid development. For the backend setup, please refer to this repository. Next, let’s install the necessary dependencies.

package.json

Now, create the zustand store to manage user credentials and utilizes middlewares for local storage integration, ensuring authentication state persists between sessions.

user-store.ts

Let’s create the axios interceptor to intercept the request and response.

axios.ts

  1. Base Configuration: Defines a base configuration for Axios, setting the base URL and enabling credentials.
  2. Axios Instances: Creates two Axios instances: one without interceptors and one with interceptors.
  3. Request Interceptor: Attaches an access token from the user’s state to the request headers if available.
  4. Response Interceptor: Checks for 401 (Unauthorized) errors. If detected, it attempts to refresh the token using a getRefreshToken function. If successful, it updates the user's state with the new token and retries the original request. If the token refresh fails with a 403 (Forbidden), it removes the user's credentials.

Create an API helper function that leverages Zod for validating both request and response payload.

Upon receiving request data, the function first validates it against the provided request schema using Zod. It then prepares the API call by constructing the URL and data payload based on the method and request data.

The function then makes the API call using either the default Axios instance or one without interceptors, depending on the specified type ("private" or "public"). After receiving the response, it parses and validates the response data against the provided response schema using Zod's safeParse method.

If the response data fails validation, an error is logged and an exception is thrown. Otherwise, the validated response data is returned.

Now, Prepare the schema for login functionality.

schema.ts

Utilize react-hook-form for smooth form submission handling.
form.ts

create a query-slice function leveraging the above api functions and schema.

Now, Let’s integrate React Query for improved data fetching and mutations.

It handles both success and error scenarios gracefully while updating user credentials and providing appropriate feedback to the user.

Now, Let’s create a API functionality to refresh the access token by creating the request and response schema same as above.

I’ve implemented sign-up, logout functionality, and user fetching to illustrate token refreshing when the access token expires, provided the refresh token remains valid. Implementing this in full detail would be lengthy, so please refer to the complete code for a comprehensive understanding.
Once completed, you’ll observe a pattern similar to the following in the network tab.

In summary, this tutorial has equipped you with the knowledge to implement a robust token refresh mechanism in React applications using Axios, Zustand, and React Query. By following these steps, you now have the tools to ensure secure user sessions and seamless experiences within your projects.

For the complete code implementation, please visit the repository

Thank you for exploring token refresh in React with us! 🛠️

--

--