Coretan kod ini ialah semua yang anda perlukan untuk mengurus keadaan pengesahan pada aplikasi tindak balas anda menggunakan API Konteks untuk mengurus keadaan pengguna merentas aplikasi.
tidak lagi membebel, mari kita selaminya.
import { createContext, Dispatch, ReactNode, SetStateAction, useContext, useEffect } from "react"; import { useLocalStorage } from "../utils/useLocalStorage"; type SignInForm = { email: string; password: string; }; type User = { id: number; email: string; }; type AuthState = User & { exp: number }; type UserContextType = { user: User | null; setUser: Dispatch<SetStateAction<AuthState | null>>; signOut: () => Promise<string | undefined>; signIn: (signInForm: SignInForm) => Promise<string | undefined>; };
Kami bermula dengan mengimport cangkuk React yang diperlukan dan cangkuk useLocalStorage tersuai. Kemudian, kami menentukan jenis TypeScript untuk sistem pengesahan kami, termasuk SignInForm, User, AuthState dan UserContextType.
const AuthDataContext = createContext<UserContextType | undefined>(undefined); export const useAuth = (): UserContextType => { const context = useContext(AuthDataContext); if (!context) { throw new Error("useAuth must be used within a UserDataProvider"); } return context; };
Di sini, kami mencipta AuthDataContext dan cangkuk useAuth tersuai. Cangkuk ini memastikan bahawa kami menggunakan konteks dalam pembekal dan menyediakan cara yang mudah untuk mengakses keadaan pengesahan kami.
export const AuthProvider = ({ children }: { children: ReactNode }) => { const [user, setUser] = useLocalStorage<AuthState | null>("user", null); // ... (other functions) return ( <AuthDataContext.Provider value={{ user, setUser, signIn, signOut }}> {children} </AuthDataContext.Provider> ); };
Komponen AuthProvider ialah teras sistem pengesahan kami. Ia menggunakan cangkuk useLocalStorage untuk mengekalkan keadaan pengguna dan memberikan nilai konteks kepada anak-anaknya.
const isJwtExpired = (unixTime: number) => { const currentTime = Math.floor(Date.now() / 1000); const timeRemaining = unixTime - currentTime; if (timeRemaining <= 0) { console.log("The JWT is expired."); setUser(null); return true; } else { const hours = Math.floor(timeRemaining / 3600); const minutes = Math.floor((timeRemaining % 3600) / 60); console.log(`Time remaining before JWT expires: ${hours} hours ${minutes} minutes`); return false; } };
Fungsi ini menyemak sama ada JWT telah tamat tempoh dan log baki masa jika masih sah.
const signOut = async () => { const res = await fetch("http://localhost:8080/auth/signout", { method: "POST" }); setUser(null); if (!res.ok) { console.log("Error signing out"); return (await res.text()) || "Something went wrong"; } };
Fungsi log Keluar membuat permintaan POST ke titik akhir log keluar dan mengosongkan keadaan pengguna.
const signIn = async (signInForm: SignInForm) => { const res = await fetch("http://localhost:8080/auth/signin", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(signInForm), }); if (!res.ok) { return (await res.text()) || "Something went wrong"; } const data = (await res.json()) as { user: User; exp: number }; if (data) { setUser({ ...data.user, exp: data.exp }); } };
Fungsi log masuk menghantar bukti kelayakan pengguna ke titik akhir log masuk dan mengemas kini keadaan pengguna dengan data respons.
useEffect(() => { if (!user) return; if (isJwtExpired(user.exp)) signOut(); }, [user]);
Kesan ini berjalan apabila keadaan pengguna berubah, menyemak sama ada JWT telah tamat tempoh dan log keluar jika perlu.
Berikut ialah contoh pelaksanaan cangkuk useLocalStorage btw
import { useState, useEffect, Dispatch, SetStateAction } from "react"; export function useLocalStorage<T>( key: string, initialValue: T ): [T, Dispatch<SetStateAction<T>>] { const [storedValue, setStoredValue] = useState<T>(() => { try { const item = localStorage.getItem(key); return item ? JSON.parse(item) : initialValue; } catch (error) { console.log(error); return initialValue; } }); const setValue: Dispatch<SetStateAction<T>> = (value) => { try { const valueToStore = value instanceof Function ? value(storedValue) : value; setStoredValue(valueToStore); localStorage.setItem(key, JSON.stringify(valueToStore)); } catch (error) { console.log(error); } }; useEffect(() => { const handleStorageChange = (event: StorageEvent) => { if (event.key === key) { setStoredValue(JSON.parse(event.newValue || "null")); } }; window.addEventListener("storage", handleStorageChange); return () => window.removeEventListener("storage", handleStorageChange); }, [key]); return [storedValue, setValue]; }
dan anda sudah selesai? perah lemon peasy yang mudah.. pastikan anda mengubah suai logik pengambilan untuk struktur api anda sendiri jika perlu.
Atas ialah kandungan terperinci Menguruskan Keadaan Auth dalam tindak balas menggunakan API useContext. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!