Estatuaren kudeaketa erreakzionatzean: adibide praktikoa

erreakzionatu
estatuaren kudeaketa
testuinguruko api
Estatuaren kudeaketa erreakzionatzean: adibide praktikoa cover image

React garatzaile askorentzat bezeroen alboko aplikazio dinamikoak eraikitzeko esparru egokia da. Aplikazio hauen izaera dinamikoa bezeroaren aldetik posible diren gaitasun eta funtzioen zerrenda zabaletik dator, eta horrek garatzaileek nabigatzailean kargatzen diren aplikazio osoak eraikitzeko aukera eman zieten segundo gutxitan, ez zen balentria. posible (edo oso astuna) web estatikoko egunetan.

Aukeren hedapen honekin, egoera kudeatzeko kontzeptua etorri zen, bezeroen alboko aplikazioetan konplexutasuna hazten den heinean, tokiko egoera mantentzeko beharra hazten doa bere baitan botilen bihurtzeraino, behar bezala kudeatzen ez bada eta eskalagarritasuna kontuan hartuta pentsatuta.

Arazo hau esparru askotan jorratu zen, ikuspegi desberdinak jarraituz eta azpiarazoen multzo ezberdinetan zentratuz, horregatik garrantzitsua da aukeratutako esparruaren ekosistema maila altua ulertzea aplikazio bakoitzaren beharrak ebaluatzeko eta horiei jarraituz ikuspegi egokia erabiltzea. metrikak. Artikulu honek egoera kudeatzeko ohiko arazoen ikuspegi laburra emango dizu eta ikuspegi desberdinak sartzen saiatuko da (useState, Context API) horri erantzun gisa. Artikulu honek irtenbide anitz aurkeztuko dituen arren, eskala txikiagoko erronketan bakarrik zentratuko da, datozen artikuluetan gai aurreratuagoak landuko ditugu.

Autentifikazio-lan-fluxua

Artikuluan zehar erakutsitako kodea hemen aurki dezakezu.

Zuzeneko aurrebista esteka bat atzi daiteke hemen.

Demagun React aplikazio baten autentifikazio-prozesua ezartzen dugun kasua.

User Login

Goiko GIFan erakusten den bezala, erabiltzaileei gure aplikazioan saioa hasteko edo erregistratzeko aukera eman nahi diegu kredentzialak erabiliz. Baliozko kredentzialak eman baziren, erabiltzailea saioa hasiko da, aplikazioa automatikoki hasierako orrialdera joango da eta erabiltzaileak aplikazioa erabiltzen jarraitu ahal izango du.

Era berean, erabiltzaileak saioa amaitzen badu, hasierako orriaren baliabideak saio-hasieraren atzean babestuta egongo dira, saioa hasteko orria izango da erabiltzaileak eskura dezakeen orri bakarra.

Lan-fluxu hau inplementazioaren aldetik pentsatuz, App izeneko osagai nagusi bat izango genuke, aplikazioaren osagaiak erabiltzailea bi orri hauetako batera birbideratuko du: Hasiera edo Saioa hasi, erabiltzailearen uneko egoerak (saioa hasita, saioa amaituta) zein izango den erabakiko du. Erabiltzailea birbideratzen den orrialdera, erabiltzailearen uneko egoeraren aldaketak (adibidez, saioa hasita hasita deskonektatuta dagoenera aldatzeak) dagokion orrialdera berehalako birbideratzea eragin beharko luke.

State

Goiko ilustrazioan erakusten den bezala, aplikazioaren osagaiak uneko egoera kontuan hartzea eta bi orrialdeetako bat bakarrik errendatzea nahi dugu - Hasiera edo Saioa hasi - uneko egoera horretan oinarrituta.

Erabiltzailea nulua bada, esan nahi du ez dugula erabiltzaile autentifikaturik, beraz, saioa hasteko orrira automatikoki nabigatzen dugu eta hasierako orria babesten dugu baldintzazko errendaketa erabiliz. Erabiltzailea existitzen bada, guk kontrakoa egiten dugu.

Orain inplementatu behar dena ondo ulertzen dugunez, azter ditzagun aukera batzuk, baina lehenik eta behin gure React proiektua konfiguratu dezagun,

Proiektuaren repo-ak frontend aldea inplementatzeko erabiliko dugun backend aplikazioaren adibide bat dauka (ez gara horretan sartuko hemen foku nagusia ez baita, baina kodea nahita sinple mantendu da, beraz, ez duzu zailtasunik izango. )

Hasierako orrialde eta osagai hauek sortzen ditugu:

  • Hasierako orria

  • Saioa hasteko orria

  • Editatu Erabiltzaile Orria

  • Nabbar osagaia

  • Erabiltzaileen goitibeherako osagaia

Hainbat orrialde dituen React aplikazio batek nabigazio egokia behar du, horretarako react-router-dom erabil dezakegu arakatzaile-bideratzaile testuinguru global bat sortzeko eta React ibilbide desberdinak erregistratzeko.


yarn add react-router-dom

Badakigu irakurle askok nahiago dutela tutoretzarekin jarraitzea, beraz, hona hemen hasierako txantiloia bizkorragoa izateko. Hasierako adar honek DaisyUI erabiltzen du aurrez definitutako TailwindCSS JSX osagaietarako. Osagai guztiak, orrialdeak eta dagoeneko konfiguratuta dagoen bideratzailea barne hartzen ditu. Tutorial honekin batera jarraitzea pentsatzen ari bazara, autentifikazio-fluxu osoa zuk zeuk eraikitzea urrats zuzenak jarraituz, hasi biltegia lehenik bideratzen. Biltegia bideratu ondoren, klonatu eta hasi hasi-hemenadar:


git clone git@github.com:<your-username>/fullstack-resourcify.git

Hasi-hemen adarra tiratzen duzunean:

  • Ireki proiektua nahiago duzun kode editorearekin

  • Aldatu direktorioa frontend/ honetara

  • Menpekotasunak instalatu: yarn

  • Hasi garapen zerbitzari bat: yarn dev·

Aurrebistak honelako itxura izan beharko luke:

Changing user name

Navbar-en errendatutako izena - goiko eskuineko aldean - aplikazioaren osagai nagusian definitutako egoera-aldagai bat da. Aldagai bera pasatzen da Navbar-era eta hasierako orrira. Goian erabilitako forma sinpleak EditPage osagaiko "izena" egoera aldagaia eguneratzen du.

Jarraian aurkezten diren bi ikuspegiak ezarpenaren xehetasunetan sartuko dira:

Lehen hurbilketa: erabili Estatua

useState()

useState React kakorik erabilienetako bat da, React Functional osagai batean egoera sortu eta aldatzeko aukera ematen du. useState osagaiak inplementazio oso sinplea du eta erabiltzeko erraza da: egoera berri bat sortzeko, useState deitu behar duzu zure egoeraren hasierako balioarekin eta useState hook bi aldagai dituen array bat itzuliko du: lehenengoa egoera da. zure egoera erreferentziatzeko erabil dezakezun aldagaia, eta bigarrena egoeraren balioa aldatzeko erabiltzen duzun funtzio bat: nahiko erraza.

Zer moduz ikusten badugu hori ekintzan? Navbar-en errendatutako izena - goiko eskuineko aldean - aplikazioaren osagai nagusian definitutako egoera-aldagai bat da. Aldagai bera pasatzen da Navbar-era eta hasierako orrira. Goian erabilitako forma sinpleak EditPage osagaiko "izena" egoera aldagaia eguneratzen du. Beheko lerroa hau da: useState hasierako egoera bat parametro gisa onartzen duen oinarrizko kako bat da eta bi balio dituzten bi aldagai itzultzen ditu, hasierako egoera duen egoera aldagaia eta egoera aldagai bererako setter funtzioa.

Apurtu dezagun, eta ikus dezagun nola gauzatu zen lehenik.

  1. “izena” egoera aldagaia sortzea:

./src/App.jsx


import { useState } from "react";

function App() {
const testValue = "CLA";
 //using the useState hook to create a state variable out of an initial value passed as an argument
 const [name, setName] = useState(testValue);
 console.log(`Rendering: &#36;{name}`);

 return (...)};

Atrezzo

Atrezzoak erreakzio-osagai baten oinarrizko eraikuntza-blokeetako bat dira, kontzeptualki, React osagai funtzional bat Javascript funtzio gisa pentsatzen baduzu, orduan atrezzoak ez dira funtzio-parametroak baino gehiago, atrezzoak eta useState amuak konbinatuz marko sendo bat eskain dezake. React aplikazio sinple batean egoera kudeatzeko.

React atrezzoak osagai pertsonalizatuei atributu gisa pasatzen zaizkie. Atrezzo gisa pasatu diren atributuak props objektutik desegituratu daitezke argumentu gisa onartzean, honen antzera:

Atrezzoa pasatzen

<Routes>
  <Route path="/" element={<Home name={name} />} /> // Passing name as a prop to
  Home Component
  <Route
    path="/user"
    element={<EditUser name={name} setName={setName} />} // passing both name and setItem function as props to EditUser component
  />
  <Route path="/login" element={<Login />} />
</Routes>

Atrezzoak osagai funtzional baten barruan onartu eta erabil daitezke funtzio arrunten argumentuen antzekoa. "izena" Etxeko osagaiari atrebitzat ematen zaiolako da, osagai berean errendatu dezakegula. Hurrengo adibidean, pasatako props-a onartzen ari gara desegituraketa sintaxia erabiliz name-propietatea atrezzo objektutik ateratzeko.

Atrezzoa onartzea

./src/pages/Home.jsx

... ...
export default function Home({name}) { //Destructuring the name property from the props object, another approach would be: Home(props.name)
 console.log("Rendering: Home");
 return (
   <div className="flex flex-col bg-white m-auto p-auto">
     <h1 className="flex py-5 lg:px-20 md:px-10 mx-5 font-bold text-2xl text-gray-800">
       Welcome {name}
     </h1>
... ...

Pro Aholkua

Ireki arakatzailearen kontsola, eta ohartu nola "izena" prop erabiltzen duten osagai guztiak berriro errendatzen diren egoera aldatzen denean. Egoera aldagai bat manipulatzean, React-ek hurrengo egoera gordeko du, zure osagaia berriro errendatuko du balio berriekin eta UI eguneratuko du.

Components Re-rendering

erabili Estatuko eragozpenak

Atrezzo-Zulaketa

Atrezzoen zulaketa osagaien hierarkia izendatzeko terminoa da, non osagai multzo batek osagai nagusi batek emandako zenbait atrezzo behar dituena, esperientziarik gabeko garatzaileek normalean erabiltzen duten konponbide arrunt bat atrezzo hauek osagai-kate osoan zehar pasatzea da, honen arazoa. Planteamendu hau da atrezzo hauetako edozein aldaketak osagaien kate osoa berriro errendatzea eragingo duela, alferrikako errendatze horien ondorioz aplikazio osoa motelduz, atrezzo hauek behar ez dituzten katearen erdiko osagaiak. atrezzoa transferitzeko euskarri gisa jardutea.

Adibidea:

  • Egoera aldagai bat definitu da aplikazioaren osagai nagusian useState() kakoaren bidez

  • Navbar osagaira izen-apropos bat pasatu da

  • Navbar-en agertoki bera onartu da eta UserDropdown osagaira beste behin ere pasa da

  • UserDropdown atrezzoa onartzen duen azken elementu umea da.

Prop-drilling

./src/App.jsx

... ...
function App() {
 const [name, setName] = useState(test);
 console.log("Rendering: App");

 return (
   <BrowserRouter>
     <div className="h-screen">
       <Navbar name={name} />

       <main className="px-4">
... ...

./src/components/Navbar.jsx

import React from "react";
import Logo from "../assets/cla.svg";
import { BiSearchAlt } from "react-icons/bi";
import { Link } from "react-router-dom";
import UserDropdown from "./UserDropdown";

export default function Navbar({ name }) {
  console.log("Rendering: Navbar");

  return (
    <>
      <div className="navbar bg-base-100 drop-shadow-sm">
        <div className="flex-1">
          <Link
            to="/"
            className="btn btn-ghost normal-case text-md md:text-xl px-2 gap-1"
          >
            <img src={Logo} className="h-6" alt="" />
            Resources
          </Link>
        </div>

        <UserDropdown name={name} />
      </div>
    </>
  );
}

Imajinatu zein zaila den React aplikazio bat mantentzea osagai geruza ezberdinekin, denak egoera bera pasatzen eta errendatzen dutenak.

Konplexutasuna eta kodearen kalitatea gero eta handiagoa

UseState eta atrezzoak erreakzio-aplikazio batean egoera kudeatzeko baliabide bakar gisa erabiliz, kode-basea azkar hazten da konplexutasuna, hamar edo ehunka egoera-aldagai kudeatu behar direlarik, elkarren bikoiztuak izan daitezkeenak, fitxategi ezberdinetan sakabanatuta eta osagaiak nahiko ikaragarriak izan daitezke, egoera-aldagai jakin batean edozein aldaketak osagaien arteko menpekotasunak arretaz kontuan hartu beharko ditu jada motela den aplikazio batean errendatze gehigarririk ekiditeko.

Bigarren hurbilketa: Context API

Context APIa React-en saiakera da atrezzoak eta useState estatuaren kudeaketarako soilik erabiltzearen eragozpenak konpontzeko, bereziki, testuinguruaren APIa osagaien zuhaitz osoan zehar atrezzoak pasatzeko beharrari buruz aurretik aipatutako arazoari erantzuten dio. Testuinguruaren erabilerarekin, globaltzat jotzen dituzun datuen egoera bat defini dezakezu eta osagaien zuhaitzeko edozein puntutatik atzitu bere egoera: ez dago zulaketa gehiagorik.

Garrantzitsua da adieraztea testuinguruko APIa hasiera batean datuen partekatze globalaren arazoa konpontzeko sortu zela, UI gaiak bezalako datuak, gure erabilera kasua den autentifikazio-informazioa, hizkuntzak eta abar), partekatu behar diren beste datu mota batzuetarako. osagai baten baino gehiagoren artean, baina ez da zertan aplikazio guztietarako globala, baliteke testuingurua ez izatea aukerarik onena, erabilera-kasuaren arabera, beste teknika batzuk kontuan izan ditzakezu, hala nola osagaien konposizioa. /composition-vs-inheritance.html) artikulu honen esparrutik kanpo dagoena.

Testuingurura aldatzen

Auth testuingurua sortzea

createContext erraza da, testuinguru-aldagai berri bat sortzen du, aukerako parametro bakarra hartzen du: testuinguru-aldagaiaren balio lehenetsia.

Ikus dezagun hau martxan, lehenik eta behin sortu karpeta berri bat "contexts" eta fitxategi berri bat bere barruan "Auth.jsx". Testuinguru berri bat sortzeko, createContext() funtzioa deitu behar dugu, itzulitako balioa esleitu hurrengo esportatuko den Auth aldagai berri bati:

./src/contexts/Auth.jsx

import { createContext } from "react";

export const Auth = createContext();

Eman autentifikazio-testuingurua

Orain aurretik sortu genuen "Auth" testuinguru-aldagaia agerian utzi behar dugu, hori lortzeko testuinguru-hornitzailea erabiltzen dugu, testuinguru-hornitzailea "balioa" prop duen osagaia da, apropos hau balio bat partekatzeko erabil dezakegu - izena - Osagaien zuhaitzean zehar, osagaien zuhaitza hornitzailearen osagaiarekin bilduta balio hori osagaien zuhaitzaren barruko edozein lekutatik eskuragarri jartzen dugu, osagarri hori osagai haur bakoitzari banan-banan pasatu beharrik gabe.

Gure autentifikazio-adibidean, aldagai bat behar dugu erabiltzaile-objektuari eusteko, eta egoera-aldagai hori manipulatzeko ezartzaile moduko bat, hau useState-ren erabilera-kasu ezin hobea da. Testuingurua erabiltzean, ziurtatu behar duzu eman nahi dituzun datuak zehazten ari zarela eta datu horiek - erabiltzailea gure adibidean - barruan habiaratuta dagoen osagaien zuhaitz guztiari pasatzen ari zarela ziurtatu behar duzu, beraz, zehaztu egoera-aldagaiaren erabiltzaile berri bat hornitzailearen osagaian eta azkenik, user eta setUser pasatzen ditugu array baten barruan hornitzaileak osagaien zuhaitzean jarriko duen balio gisa:

./src/contexts/Auth.jsx

import { createContext, useState } from "react";

export const Auth = createContext();

export const AuthProvider = ({ children }) => {
  const [user, setUser] = useState(null);
  return <Auth.Provider value={[user, setUser]}>{children}</Auth.Provider>;
};

Egin dezakegun beste gauza bat gure "izena" egoera aldagaia aplikazioaren osagai nagusitik Auth testuingurura eraman eta habiaratutako osagaietara eramatea da:

import { createContext, useState } from "react";

export const Auth = createContext();

export const AuthProvider = ({ children }) => {
  const [user, setUser] = useState(null);
  const [name, setName] = useState("CLA");
  return <Auth.Provider value={[name, setName]}>{children}</Auth.Provider>;
};

Orain geratzen dena gure aplikazioa esportatu berri dugun AuthProvider osagai berean habiatzea da.

./src/main.jsx:

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import { AuthProvider } from "./contexts/Auth";

import "./index.css";

ReactDOM.createRoot(document.getElementById("root")).render(
  <AuthProvider>
    <App />
  </AuthProvider>
);

Auth.Provider-en barruan haur-propioa errendatzen ari garenez, AuthProvider osagaiaren barruan habiaratuta dauden elementu guztiak Auth.Provider-i pasatu diogun balio-propioa kontsumitzeko gai dira orain. Nahasia dirudi, baina behin probatzen duzunean, saiatu egoera global bat ematen eta kontsumitzen. Azken finean, Testuinguruko APIarekin esperimentatu ondoren bakarrik izan nuen zentzua.

Autentifikazio-testuingurua kontsumitzen

Azken urratsa zuzena da, "useContext" testuinguru-kakoa erabiltzen dugu "Auth"-ren testuinguru-hornitzaileak ematen duen balioa atzitzeko, hau da, gure kasuan user eta setUser dituen array-a, hurrengo kodean, gai gara. erabili useContext Navbar barruko Auth testuingurua kontsumitzeko. Hau bakarrik posible da Navbar aplikazioaren osagaiaren barruan habiaratuta dagoelako eta AuthProvider aplikazioaren osagaiaren inguruan biltzen denez, balio-propioa useContext amua erabiliz soilik kontsumitu daiteke. React-ek beste tresna ikaragarri bat eskaintzen du kutxatik kanpo globalki atzi daitezkeen datu guztiak kudeatzeko eta kontsumitzaileen edozein osagaik ere manipulatzeko.

./src/components/Navbar.jsx

export default function Navbar() {
 const [name, setName] = useContext(Auth);
 console.log(name)

 return (...)};

Kontuan izan nola ez dugun gehiago atrezzorik onartzen Navbar() osagai funtzionalean. UseContext(Auth) erabiltzen ari gara Auth testuingurua kontsumitzeko, izena eta setName hartuz. Horrek esan nahi du ez dugula atrezzoa Navbar-era gehiago pasatu behar:

./src/App.jsx

// ... //
return (
   <BrowserRouter>
     <div className="h-screen">
       <Navbar/> // no need to pass prop anymore
// ... //

Autentifikazio-testuingurua eguneratzen

Emandako setName funtzioa ere erabil dezakegu "izena" egoera aldagaia manipulatzeko:

./src/pages/EditUser.jsx

export default function EditUser() { // no need to accept props anymore
 const [name, setName] = useContext(Auth); // grabbing the name and setName variables from Auth context
 console.log("Rendering: EditUser");

useReducer() amua aurkezten

Aurreko adibidean testuinguru APIa erabili genuen osagaien zuhaitzean behera gure egoera kudeatzeko eta partekatzeko, baliteke oraindik useState erabiltzen ari garela gure logikaren oinarri gisa, eta hau gehienetan ondo dago, gure egoera oraindik objektu sinplea baita. une honetan, baina gure autentifikazio-fluxuaren gaitasunak zabalduko bagenitu, zalantzarik gabe, une honetan saioa hasita dagoen erabiltzailearen posta elektronikoa baino gehiago gorde beharko dugu, eta horra itzuliko gara lehengo mugetara. useState egoera konplexuarekin erabiltzeak, zorionez, React-ek arazo hau konpontzen du useState-ren alternatiba bat emanez egoera konplexua kudeatzeko: sartu useReducer.

useReducer useState-ren bertsio orokortzat har daiteke, bi parametro hartzen ditu: erreduktore funtzioa eta hasierako egoera.

Hasierako egoerarako ez da ezer interesgarri nabarmentzen, magia erreduktorearen funtzioaren barruan gertatzen da: gertatu den ekintza mota egiaztatzen du, eta ekintza horren arabera, erreduktoreak egoerari zer eguneraketa aplikatu eta bere balio berria itzuliko du. .

Beheko kodeari begiratuta, murrizte funtzioak bi ekintza mota ditu:

  • "LOGIN": kasu horretan, erabiltzailearen egoera eguneratuko da ekintza-kargaren barruan emandako erabiltzaile-kredentzial berriekin.

  • "LOGOUT": kasu horretan, erabiltzailearen egoera tokiko biltegiratzetik kenduko da eta null bihurtuko da.

Garrantzitsua da kontutan izan ekintza objektuak zer logika aplikatu behar den zehazten duen mota-eremu bat eta aukerako karga-eremu bat logika hori aplikatzeko beharrezkoak diren datuak emateko.

Azkenik, useReducer amuak uneko egoera eta erreduktoreari ekintza bat pasatzeko erabiltzen dugun bidalketa-funtzioa itzultzen ditu.

Gainerako logikarako, aurreko adibidearen berdina da:

./src/contexts/Auth.jsx

import { createContext, useEffect, useReducer, useState } from "react";

export const Auth = createContext();
import { createContext, useReducer } from "react";

export const Auth = createContext();
const reducer = (state, action) => {
  switch (action.type) {
    case "LOGIN":
      return { user: action.payload };

    case "LOGOUT":
      localStorage.removeItem("user");
      return { user: null };

    default:
      break;
  }
};

export const AuthProvider = ({ children }) => {
  const [state, dispatch] = useReducer(reducer, {
    user: null,
  });

  return (
    <Auth.Provider value={{ ...state, dispatch }}>{children}</Auth.Provider>
  );
};

Ekintzak bidaltzea setState setter funtzioa erabili beharrean - adibidez: setName -

Aipatu berri dugun bezala, bidalketa funtzioa erabiltzen dugu erreduktoreari ekintza bat pasatzeko, hurrengo kodean, LOGIN ekintza bat abiarazten dugu eta erabiltzailearen posta elektronikoa karga gisa ematen dugu, orain erabiltzailearen egoera eguneratuko da eta aldaketa hau abiaraziko da. erabiltzailearen egoerara harpidetutako osagai guztien birrendaketa. Garrantzitsua da azpimarratzea berriro errendatzea egoeraren aldaketa erreal bat gertatzen bada soilik abiaraziko dela, ez da berriro errendatuko erreduktoreak aurreko egoera bera itzultzen badu.

export default function Login() {
 const { dispatch } = useContext(Auth);


 const handleLogin = async (e) => {
   // Updating the global Auth context
   dispatch({ type: "LOGIN", payload: {email: email.current.value} });
 };

 return (...)};

Erabiltzaileen saioa

JWT Local storage

Pro Aholkua

Kontuan izan saio-hasiera arrakastatsu baten ondoren jasotzen dugun erabiltzaile-objektua nola gordetzen den orain localStorage-n.

Saioa hasteko kako pertsonalizatua

Orain useReducer-i ongi jabetuta gaudenean, gure saioa hasteko eta amaitzeko logika bere kako pertsonalizatuetan gehiago bil ditzakegu, Saioa hasteko kakoari dei bakar baten bidez, saioa hasteko biderako API dei bat kudeatu ahal izango dugu, erabiltzaile berria berreskuratu. kredentzialak eta gorde itzazu tokiko biltegian, bidali LOGIN dei bat erabiltzailearen egoera eguneratzeko, akatsen kudeaketari aurre egiten dion bitartean:

./src/hooks/useLogin.jsx

import { useContext, useState } from "react";
import { Auth } from "../contexts/Auth";

export const useLogin = () => {
  const [error, setError] = useState(null);
  const [isLoading, setIsLoading] = useState(false);

  const { dispatch } = useContext(Auth);

  const login = async (email, password) => {
    setIsLoading(true);
    setError(null);

    try {
      const response = await fetch("/api/users/login", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ email, password }),
      });

      const json = await response.json();

      if (json.name === "Error") {
        setError(json.message);
        setIsLoading(false);
      }

      if (!response.ok) {
        setIsLoading(false);
        setError(json);
      }

      if (response.ok) {
        // Save the user and token in the localstorage
        localStorage.setItem("user", JSON.stringify(json));

        // Updating the global Auth context
        dispatch({ type: "LOGIN", payload: json });

        setIsLoading(false);
      }
    } catch (error) {
      console.log(error);
    }
  };

  return { error, isLoading, login };
};

Oharra: irakurleen artean React erabiltzaile aurreratuagoentzat, agian galdetuko duzu zergatik ez genuen erabili useReducer-en hasierako alferraren funtzioa erabiltzailearen kredentzialak berreskuratzeko, useReducer-ek init funtzioa deitzen den hirugarren aukerako parametro bat onartzen du, funtzio hau erabiltzen da kasuan. logika batzuk aplikatu behar ditugu egoeraren hasierako balioa lortu baino lehen, hau aukeratu ez genuen arrazoia kezkak bereizteko kontu sinplea da, modu honetan kodea ulertzeko errazago da eta, ondorioz, mantentzea errazagoa da. .

Saioa hasteko orria

Hona hemen gure Saio-hasiera orriaren goiko aldea saio-hasiera-funtzioa ateratzeko useLogin() amua erabili ondoren eta erabiltzaile batek bidalitako kredentzialekin saioa hasteko funtzioa dei egin ondoren:

// ... ... //
export default function Login() {
 const { login, isLoading, error } = useLogin();
 console.log("Rendering: Login");
 const email = createRef(null);
 const password = createRef(null);

 const handleLogin = async (e) => {
   await login(email.current.value, password.current.value);
 };
 return (...)
// ... ... //

Erabiltzaileak formularioa bidaltzen duenean Bidali funtzioa ere desgaitzen ari gara:

<button
  onClick={handleLogin}
  disabled={isLoading}
  className="btn btn-square w-full bg-gray-100 text-gray-600 hover:bg-gray-300 border-none"
>
  {isLoading && "A moment please!"}
  {!isLoading && "Login"}
</button>

Eta gure backendetik jasotzen ditugun autentifikazio-erroreak errendatuz:

{
  error && <span className="text-red-500 p-2">{error.message}</span>;
}

Rendering Errors

Erabiltzailearen egoera mantentzea

Galdetzen ari zara zergatik gorde behar dugun erabiltzailearen objektua biltegiratze lokalean, besterik gabe, erabiltzailea saioa hasita mantendu nahi dugu tokena iraungi ez den bitartean. LocalStorage erabiltzea JSON zatiak gordetzeko modu bikaina da, gure adibidean bezala. Kontuan izan nola egoera ezabatzen den orria saioa hasi ondoren freskatzen baduzu. Hau erraz konpon daiteke useEffect hook bat erabiliz, lokalStorage-n gordetako erabiltzaile-objektu bat ote dugun egiaztatzeko; halakorik badago, erabiltzailea automatikoki hasten dugu saioa:

// ... ... //
export const AuthProvider = ({ children }) => {
  const [state, dispatch] = useReducer(reducer, {
    user: null,
  });

  useEffect(() => {
    const user = JSON.parse(localStorage.getItem("user"));

    if (user) {
      return dispatch({ type: "LOGIN", payload: user });
    }
  }, []);

  return (
    <Auth.Provider value={{ ...state, dispatch }}>{children}</Auth.Provider>
  );
};

Amaitzeko kako pertsonalizatuak

Gauza bera aplikatzen da Logout kakoarekin, hemen LOGOUT ekintza bat bidaltzen ari gara egoeratik eta tokiko biltegiratzetik uneko erabiltzailearen kredentzialak kentzeko:

./src/hooks/useLogout.jsx

import { useContext } from "react";
import { Auth } from "../contexts/Auth";

export const useLogout = () => {
  const { dispatch } = useContext(Auth);

  const logout = () => {
    // delete user from the localstorage
    localStorage.removeItem("user");
    // Wipe out the Auth context (user:null) / dipatch 'LOGOUT'
    dispatch({ type: "LOGOUT" });
  };

  return { logout };
};

Erabiltzailearen saioa amaitu

Erabiltzaile bati saioa amaitzeko, gehi diezaiogun klik-gertaera bat UserDropdown.jsx-en dagoen Amaitzeko botoian, eta kudea dezagun horren arabera:

./src/components/UserDropdown.jsx

// Extracting the logout function from useLogout() and handling the click event listener //
export default function UserDropdown() {
 const { user } = useContext(Auth);
 const { logout } = useLogout();
 console.log("Rendering: UserDropdown");

 const handleLogout = () => {
   logout();
 };
// ... ... //

// Adding a click event listener to logout button //
<li>
   <button onClick={handleLogout}>Logout</button>
</li>
// ... ... //

User Logout

Erreakzio Ibilbideak babestea

Gure aplikazioa inplementatzeko azken urratsa erabiltzailearen nabigazioa kontrolatzeko erabiltzailearen egoera globala aprobetxatzea da, zein jokabide lortu behar dugun abisu azkar bat: hasieran erabiltzailea saio-hasiera-orritik agurtzen da, une horretatik aurrera erabiltzailea hasierako orrialdera bakarrik sar daiteke. Saio-hasiera arrakastatsua egin ondoren, era berean, erabiltzailea saioa hasteko orrira birbideratuko da saioa amaitzean.

Erreakzio-router-dom liburutegiaren laguntzaz lortzen dugu 2 ibilbide definituz: "/" eta "/login", bide bakoitzean zein osagai errendatu kontrolatzen dugu autentifikazio-egoera globala erabiliz., auth balioes null autentifikatu gabeko erabiltzaile bat adierazten du eta alderantziz:

./src/App.jsx

import { BrowserRouter, Navigate, Route, Routes } from "react-router-dom";
import "./App.css";
import Navbar from "./components/Navbar";
import Home from "./pages/Home";
import Login from "./pages/Login";
import { useContext } from "react";
import { Auth } from "./contexts/Auth";

function App() {
  const { user } = useContext(Auth);
  return (
    <BrowserRouter>
      <div className="h-screen">
        <Navbar />
        <main className="px-4">
          <Routes>
            <Route
              path="/"
              element={user ? <Home /> : <Navigate to="/login" />}
            />
            <Route
              path="/login"
              element={!user ? <Login /> : <Navigate to="/" />}
            />
          </Routes>
        </main>
      </div>
    </BrowserRouter>
  );
}

export default App;

Resumen diagrama

Diagram

Biltzea

Artikulu honetan egoera-kudeaketa autentifikazio-fluxu baterako ezartzearen erabilera-kasu sinple baina oso ohikoa jorratzen saiatu gara, planteamendu desberdinak, bakoitzaren arrazoiak eta haien konpromezuak aztertuz. Bezeroaren alboko esparruetan eta bereziki React-en egoera kudeaketa frontend komunitatean gehien hitz egiten den gaietako bat da, zure aplikazioaren errendimendua eta eskalagarritasuna egin edo hautsi ditzakeelako. Estatuaren kudeaketaren arazo hau konpontzen saiatzen diren teknika, eredu, liburutegi eta tresna ezberdinen kopurua izugarria da, gure helburua praktiken ulermen sendoa ematea zen, zure aplikazioan inplementatu ahal izateko, aurreratuago izateko. Aplikazio konplexuagoetan egoera kudeatzeko teknikak eta ereduak, begiratu gure hurrengo artikulua, non React-en egoera-kudeaketa eskalagarrirako redux-ean sartzen garen.

Laster

ContextAPI vs Redux Toolkit

Redux-ek urte asko izan zituen komunitatean Redux tresna-kitaren aurretik, izan ere, RTK hasierako txantiloi gisa sartu zen aplikazio berrietan redux egoeraren kudeaketa abiarazteko (hasierako izena "redux-starter-kit" zen 2019ko urrian), nahiz eta gaur egun, Redux-en mantentzaileen eta komunitatearen arteko adostasun orokorra dago Redux toolkit-a redux-ekin lan egiteko modu egokia dela. RTX-k Redux logika asko abstraitzen du, eta horrek erabilera errazten du, askoz hitz gutxiagorekin, eta garatzaileak animatzen ditu. jarraitu praktika onak, bien arteko desberdintasun nagusi bat Redux iritzirik gabekoa izateko eraiki zela da, gutxieneko API bat eskainiz eta garatzaileek lan astunena egitea espero dute beren liburutegiak idatziz zeregin arruntetarako eta kode-egituraz arduratuz. honek garapen-denbora motela eta kode nahasia eragin zuen, Redux toolkit abstrakzio-geruza gehigarri gisa gehitu zen garatzaileak bere hutsune arruntetan erortzea ekiditeko, ikusi dokumentazio ofiziala informazio gehiago lortzeko eta bere arduradunen arrazoibideak hemen.


Career Services background pattern

Lanbide Zerbitzuak

Contact Section background image

Jarrai gaitezen harremanetan

Code Labs Academy © 2024 Eskubide guztiak erreserbatuta.