- vừa được xem lúc

Setup axios - chuyển trang bằng react-router-dom trong interceptor

0 0 20

Người đăng: Nguyễn Minh nhật

Theo Viblo Asia

Giới thiệu

Bài viết này giải quyết 2 vấn đề

  1. Cách cài đặt axios
  2. Các sử dụng được react-router-dom trong axios interceptor để chuyển trang mà không bị load lại cả website

Nội dung

Cài đặt axios

  • npm: npm install axios

  • yarn: yarn add axios

Chuyển trang trong interceptor bằng react-router-dom

Vấn đề

Trong reactjs hoặc trong bất kỳ single page app nào chúng ta đều không mong muốn phải re-load toàn bộ trang, việc này làm trình duyệt phải tải lại hết tài nguyên (js, css, image, font,..) làm giảm trải nghiệm người dùng mà lại không tận dụng được sức mạnh của single page app. Để di chuyển qua lại trong các page chúng ta thường sử dụng hook useHistory/useNavigate của react-router-dom, tuy nhiên interceptor của axios lại không phải là 1 react-component nên không thể sử dụng hook được. Vậy thì phải làm sao đây?

Cách giải quyết

  • Sử dụng cách khác react-router-dom mà cho phép di chuyển trang mà không cần dùng hook
  • Gọi interceptor vào trong react-component để dùng hook
Logic

Tất nhiên trong bài viết này mình sẽ giải quyết theo hướng thứ 2, mindset như sau:

  • Làm sao để set được interceptor trong component?
    • Gọi interceptor ngay App.tsx của project, khỏi tạo 1 lần duy nhất. So ease!
  • Nếu set được rồi thì làm sao những chỗ cần dùng axios sẽ phải sử dụng như thế nào
    • Để những nơi khác ( component, function) có thể dùng được thì cần dùng chung instance với axios interceptor trong App.tsx phía trên

Coding

B1: Gọi interceptor ngay trong component đầu tiên App.tsx
Ở đây mình ví dụ nếu status 401 thì sẽ redirect sang /login

import axios from 'axios'; function App() { const navigate = useNavigate(); const axiosInstance = axios.create({ baseURL: "http://localhost:3000/api", }); axiosInstance.interceptors.request.use((config) => { // handle before request is sent return config; }, (error) => { // handle request error return Promise.reject(error); }); axiosInstance.interceptors.response.use((response) => { // handle response data return response; }, (error) => { // handle response un-authen error if (error.response.status === 401) { navigate("/login"); } return Promise.reject(error); }); return (<RouterProvider router={routers} fallbackElement={"loading..."} />) }

Vậy là xong vấn đề navigate 💪

B2: Làm sao để sử dụng lại được axiosInstance vì mình chỉ custom interceptor của nó thôi, nếu dùng instance khác thì lại chẳng còn navigate nữa, chẳng nhẽ export từ App.tsx ra???

Để đưa về chung 1 instance thì có 2 cách.

  • Cách 1: Sử dụng singleton pattern
  • Cách 2: Sử dụng lại chính instance của thư viện

Ở đây mình sẽ dùng cách 2, còn cách 1 anh em tự tìm hiểu thêm nhé. Anh em chỉ cần thay axiosInstance bằng axios được import trực tiếp từ thư viện là xong

import axios from 'axios'; function App() { const navigate = useNavigate(); axios.defaults.baseURL = "http://localhost:3000/api"; axios.interceptors.request.use((config) => { // handle before request is sent return config; }, (error) => { // handle request error return Promise.reject(error); }); axios.interceptors.response.use((response) => { // handle response data return response; }, (error) => { // handle response un-authen error if (error.response.status === 401) { navigate("/login"); } return Promise.reject(error); }); return (<RouterProvider router={routers} fallbackElement={"loading..."} />) }

Vậy là xong, quá đơn giản 👍

B3: Fix bug

Khi đến bước này anh em chạy chắc chắn sẽ báo lỗi vì mình sử dụng useNavigate ở ngoài RouterProvider. Vậy thì chỉ cần đưa đống code này vào trong RouterProvider là được. Ở đây mình đang dùng react-router-dom 6.8 có thể hơi khác với mọi người. Nhưng mindset là đưa phần setup interceptor vào phía trong RouterProvider để dùng được useNavigate hoặc useHistory


import axios from "axios"; const OutletContainer = () => { const navigate = useNavigate(); axios.defaults.baseURL = "http://localhost:3000/api"; axios.interceptors.request.use((config) => { // handle before request is sent return config; }, (error) => { // handle request error return Promise.reject(error); }); axios.interceptors.response.use((response) => { // handle response data return response; }, (error) => { // handle response un-authen error if (error.response.status === 401) { navigate("/login"); } return Promise.reject(error); }); return <Outlet />
} const ALL_ROUTES: RouteObject[] = [...HOME_ROUTES, ...PRODUCT_ROUTES, ...CATEGORY_ROUTES];
const CONTAINER_ROUTES: RouteObject[] = [ { element: <OutletContainer />, children: ALL_ROUTES, errorElement: <ErrorPage /> },
] export default createBrowserRouter(CONTAINER_ROUTES);
Cách sử dụng ✅
import axios from 'axios'; const getProducts = () => { return axios.get("/products"); }

Tổng kết

Vậy là xong, chúc anh em hiểu bài. Khó chỗ nào contact với mình

Bình luận

Bài viết tương tự

- vừa được xem lúc

Cùng tìm hiểu về các hook trong React hooks

Đối với ai đã từng làm việc với React thì chắc hẳn đã có những lúc cảm thấy bối rối không biết nên dùng stateless (functional) component hay là stateful component. Nếu có dùng stateful component thì cũng sẽ phải loay hoay với đống LifeCycle 1 cách khổ sở Rất may là những nhà phát triển React đã kịp

0 0 100

- vừa được xem lúc

Khi nào nên (và không nên) sử dụng Redux

. Công việc quản lý state với những hệ thống lớn và phức tạp là một điều khá khó khăn cho đến khi Redux xuất hiện. Lấy cảm hứng từ design pattern Flux, Redux được thiết kế để quản lý state trong các project JavaScript.

0 0 127

- vừa được xem lúc

ReactJS: Props và State

Nếu bạn đã học ReactJS hay React Native, bạn sẽ thấy các Props và State được sử dụng rất nhiều. Vậy chính xác chúng là gì? Làm thế nào để chúng ta sử dụng chúng đúng mục đích đây.

0 0 59

- vừa được xem lúc

State và Props trong Reactjs

Hello các bạn, tiếp tục seri tìm hiểu về ReactJs hôm nay mình xin giới thiệu đến các bạn hai thứ mình cho là thú vị nhất của ReactJs là State và Props. State bạn có thể hiểu đơn giản là một nơi mà bạn lưu trữ dữ liệu của Component, từ đó bạn có thể luân chuyển dữ liệu đến các thành phần trong Compon

0 0 54

- vừa được xem lúc

Memoization trong React

. 1.Introduction. Memoization có liên quan mật thiết đến bộ nhớ đệm, và dưới đây là một ví dụ đơn giản:. const cache = {}.

0 0 51

- vừa được xem lúc

Nâng cao hiệu suất React Hooks với React.memo, Memoization và Callback Functions

1.Ngăn Re-render và React.memo. React.

0 0 80