Heim > Web-Frontend > js-Tutorial > Hauptteil

Verwalten des Auth-Status in React mithilfe der useContext-API

王林
Freigeben: 2024-09-08 22:34:33
Original
813 Leute haben es durchsucht

Managing Auth State in react using useContext API

Dieses Code-Snippet ist alles, was Sie brauchen, um den Authentifizierungsstatus Ihrer React-Anwendung zu verwalten. Verwendet die Kontext-API, um den Benutzerstatus in der gesamten Anwendung zu verwalten.

Kein Geplapper mehr, lass uns einfach eintauchen.

Importe und Typdefinitionen

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>;
};
Nach dem Login kopieren

Wir beginnen mit dem Importieren der erforderlichen React-Hooks und eines benutzerdefinierten useLocalStorage-Hooks. Anschließend definieren wir TypeScript-Typen für unser Authentifizierungssystem, einschließlich SignInForm, User, AuthState und UserContextType.

Erstellen des Kontexts und des benutzerdefinierten Hooks

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;
};
Nach dem Login kopieren

Hier erstellen wir den AuthDataContext und einen benutzerdefinierten useAuth-Hook. Dieser Hook stellt sicher, dass wir den Kontext innerhalb eines Anbieters verwenden und bietet eine bequeme Möglichkeit, auf unseren Authentifizierungsstatus zuzugreifen.

AuthProvider-Komponente

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>
  );
};
Nach dem Login kopieren

Die AuthProvider-Komponente ist der Kern unseres Authentifizierungssystems. Es verwendet den useLocalStorage-Hook, um den Benutzerstatus beizubehalten und den Kontextwert für seine untergeordneten Elemente bereitzustellen.

JWT-Ablaufprüfung

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;
  }
};
Nach dem Login kopieren

Diese Funktion prüft, ob das JWT abgelaufen ist und protokolliert die verbleibende Zeit, wenn es noch gültig ist.

Abmeldefunktion

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";
  }
};
Nach dem Login kopieren

Die SignOut-Funktion stellt eine POST-Anfrage an den Signout-Endpunkt und löscht den Benutzerstatus.

Anmeldefunktion

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 });
  }
};
Nach dem Login kopieren

Die SignIn-Funktion sendet die Anmeldeinformationen des Benutzers an den Anmeldeendpunkt und aktualisiert den Benutzerstatus mit den Antwortdaten.

useEffect für die JWT-Ablaufprüfung

useEffect(() => {
  if (!user) return;
  if (isJwtExpired(user.exp)) signOut();
}, [user]);
Nach dem Login kopieren

Dieser Effekt wird immer dann ausgeführt, wenn sich der Benutzerstatus ändert. Dabei wird überprüft, ob das JWT abgelaufen ist, und bei Bedarf abgemeldet.

Hier ist übrigens eine Beispielimplementierung des useLocalStorage-Hooks

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];
}
Nach dem Login kopieren

und schon bist du fertig? easy peasy Lemon Squeezy. Stellen Sie sicher, dass Sie bei Bedarf die Abruflogik für Ihre eigene API-Struktur ändern.

Das obige ist der detaillierte Inhalt vonVerwalten des Auth-Status in React mithilfe der useContext-API. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:dev.to
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!