Sử dụng useReducer và useContext để làm global state
Thông thường chúng ta sẽ dùng một nhà kho để chứa dữ liệu state
như Redux, một component container bọc ở nút đầu tiên trong app, các component con bên trong có thể truy xuất và cập nhập các dữ liệu một cách dễ dàng
Với các API mới được React bổ sung là useState
, createContext
, useContext
chúng ta có thêm một lựa chọn để làm nhà kho mà ko cần dùng đến Redux
Ví dụ chúng ta có 3 dữ liệu như bên dưới
const teamMembersNames = ["John", "Mary", "Jason", "David"];
const [sharing, setSharing] = React.useState([]);
const [help, setHelp] = React.useState([]);
const [pairing, setPairing] = React.useState(teamMembersNames);
Câu hỏi là làm sao chúng ta đưa dữ liệu vào nhà kho. Chúng ta sẽ dùng API createContext
(tạo em cái kho)
Khi sử dụng React.createContext
chúng ta sẽ nhận về 2 component là Provider
(anh tung) và Consumer
(em hứng).
// ./src/utils/store.js
export const StoreContext = React.createContext(null);
export default ({ children }) => {
// các em đã vào nhà kho
const teamMembersNames = ["John", "Mary", "Jason", "David"];
const [sharing, setSharing] = React.useState([]);
const [help, setHelp] = React.useState([]);
const [pairing, setPairing] = React.useState(teamMembersNames);
const store = {
sharing: [sharing, setSharing],
help: [help, setHelp],
pairing: [pairing, setPairing]
};
return (
<StoreContext.Provider value={store}>{children}</StoreContext.Provider>
);
};
Để các component bên trong <App/>
đều dùng được <Consumer />
// ./index.js
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import StoreProvider from "./utils/store";
ReactDOM.render(
<StoreProvider>
<App />
</StoreProvider>,
document.getElementById("root")
);
Với bất kỳ component nào muốn sử dụng, để lấy được dữ liệu trong store, chúng ta sử dụng useContext
import React from "react";
import { StoreContext } from "../utils/store";
const SomeComponent = () => {
// dữ liệu dùng chung
const { sharing } = React.useContext(StoreContext);
};
Hoặc nếu thích dùng cách viết render props, có thể dùng luôn component <Consumer/>
<StoreContext.Consumer>
{store => <InputComponent store={store} />}
</StoreContext.Consumer>
Ứng dụng làm useAuth
Một trong những ví dụ dễ thấy, phần dữ liệu nên đưa vào nhà kho chung là phần thông tin user đang đăng nhập
Chúng ta sẽ cần 3 phần
- Khai báo một nhà kho bằng
createContext
- Bộ
reducer
làm nhiệm vụ cập nhập xử lýstate
- Một hook tùy biến
useAuth
cung cấp các API cần thiết để tương tác với nhà kho chung đã khai báo - AuthProvider.js Khai báo nhà kho (bản rút gọn)
// AuthProvider.js
import authReducer from "authReducer";
export const AuthContext = React.createContext(null);
export const AuthProvider = ({ children }) => {
// khởi tạo
const [state, dispatch] = useReducer(authReducer, {});
return (
<AuthContext.Provider value={[state, dispatch]}>
{children}
</AuthContext.Provider>
);
};
- authReducer.js (bản rút gọn)
// authReducer.js
function authReducer(state, action) {
switch (action.type) {
case "login":
const { authResult, user } = action;
const expiresAt = authResult.expiresIn * 1000 + new Date().getTime();
localStorage.setItem("expires_at", JSON.stringify(expiresAt));
localStorage.setItem("user", JSON.stringify(user));
return { user, expiresAt };
case "logout":
localStorage.removeItem("expires_at");
localStorage.removeItem("user");
return { user: {}, expiresAt: null };
default:
return state;
}
}
- Một hook tùy biến
useAuth
// useAuth.js
import { AuthProvider } from "AuthProvider";
export const useAuth = () => {
const { state, dispatch } = userContext(AuthContext);
const login = () => {
// làm gì đó ở đây
}
const logout = () => {
// làm gì đó ở đây
dispatch({ type: "logout" })
}
// ... còn một số thức khác
const isAuthenticated = () => {
return state.expiresAt && new Date().getTime() < state.expiresAt;
};
// ... còn một số thức khác
return {
isAuthenticated,
user: state.user,
userId: state.user ? state.user : null;
login,
logout,
handleAuthentication
}
}
Với cách làm này, bất kỳ component nào sử dụng useAuth
đều sẽ truy xuất đến một kho dữ liệu chung
import useAuth from "useAuth";
const MyCom = () => {
const {
/* quá trời thứ linh tinh trả về */
} = useAuth();
//...
};
TopDev via Vuilaptrinh
- B BenQ RD Series – Dòng Màn Hình Lập Trình 4k+ Đầu Tiên Trên Thế Giới
- i iOS 18 có gì mới? Có nên cập nhật iOS 18 cho iPhone của bạn?
- G Gamma AI là gì? Cách tạo slide chuyên nghiệp chỉ trong vài phút
- P Power BI là gì? Vì sao doanh nghiệp nên sử dụng PBI?
- K KICC HCMC x TOPDEV – Bước đệm nâng tầm sự nghiệp cho nhân tài IT Việt Nam
- T Trello là gì? Cách sử dụng Trello để quản lý công việc
- T TOP 10 SỰ KIỆN CÔNG NGHỆ THƯỜNG NIÊN KHÔNG NÊN BỎ LỠ
- T Tìm hiểu Laptop AI – So sánh Laptop AI với Laptop thường
- M MySQL vs MS SQL Server: Phân biệt hai RDBMS phổ biến nhất
- S SearchGPT là gì? Công cụ tìm kiếm mới có thể đánh bại Google?