Redux
Trong dự án sẽ dùng redux để trao đổi dữ liệu giữa các component với nhau hoặc để lưu trữ state cho sử dụng cho việc khác
Base sẽ sử dụng redux toolkit để việc khai báo đỡ vất vả hơn
1. Khai báo
Tạo file với tên là Chức năng + Slice
trong thư mục redux/slices
. Ví dụ:
📦redux
┣ 📂slices
┃ ┣ 📜UserSlice.tsx
┃ ┣ 📜MenuSlice.tsx
Trong file UserSlice sẽ có nội dung như sau:
import { createSlice, PayloadAction } from "@reduxjs/toolkit"
import { IAccountInfo } from "../../types"
// Khai báo initValue
const initialState: IAccountInfo = {}
const UserSlice = createSlice({
name: "user", //Nên đặt theo chức năng
initialState, //Giá trị khởi tạo
reducers: {
//Tạo các action
loginUser: (_, action: PayloadAction<IAccountInfo>) => {
return action.payload // Trả về state trong store trong trường hơp này là dữ liệu truyền vào khi gọi dispatch
},
logoutUser: () => {
return initialState
},
},
})
// Export các action ra để sử dụng
export const { loginUser, logoutUser } = UserSlice.actions
// Export reducer để import trong file redux/store.tsx
export default UserSlice.reducer
Trong file MenuSlice sẽ có nội dung như sau:
import { createSlice } from "@reduxjs/toolkit"
// Khai báo type của state
interface IMenuState {
isOpen: boolean
}
// Khai báo initValue
const initialState: IMenuState = {
isOpen: false,
}
const MenuSlice = createSlice({
name: "menu", //Nên đặt theo chức năng
initialState, //Giá trị khởi tạo
reducers: {
//Tạo các action
openMenu: (state) => {
state.isOpen = true //Sửa lại state
},
closeMenu: (state) => {
state.isOpen = false //Sửa lại state
},
toggleMenu: (state) => {
state.isOpen = !state.isOpen //Sửa lại state
},
},
})
// Export các action ra để sử dụng
export const { openMenu, closeMenu, toggleMenu } = MenuSlice.actions
// Export reducer để import trong file redux/store.tsx
export default MenuSlice.reducer
2. Thay đổi state trong store
Để thay đổi state trong store thì ta sẽ gọi action tương ứng khai báo trong reducer ra trong hàm dispatch
import { loginUser } from "../redux/slices/UserSlice" // Import action
import store from "@app/redux/store" // Import store
import { useDispatch } from "react-redux" // Import hook
export default function Login(): JSX.Element {
const dispatch = useDispatch() // Khai báo sử dụng hook useDispatch
const login = (loginData) => {
loginMutation.mutate(loginData, {
onSuccess: (res) => {
dispatch(loginUser(res)) // Đây là cách dispatch dùng hook
store.dispatch(loginUser(res)) // Đây là cách dispatch không dùng hook
},
})
}
}
Lưu ý: Chỉ sử dụng cách dispatch không dùng hook nếu đoạn code xử lý không nằm trong React Component. Ví dụ như api/Fetcher.tsx
3. Lấy state trong store
Để lấy state trong store thì dùng useSelector
hoặc getState
từ store
import store from "@app/redux/store" // Import store
import { useSelector } from "react-redux" // Import hook
import { IRootState } from "@app/redux/reducers/RootReducer" // Import type của state
export default function Login(): JSX.Element {
const user = useSelector((state: IRootState) => state.user) // Lấy state muốn sử dụng từ store ra
const checkUserLoggedIn = () => {
if (user.accessToken) {
//Đây là cách lấy dùng hook
return true
}
if (store.getState().user.accessToken) {
//Đây là cách lấy không dùng hook
return true
}
return false
}
}
Lưu ý: Chỉ sử dụng cách lấy state không dùng hook nếu đoạn code xử lý không nằm trong React Component. Ví dụ như api/Fetcher.tsx