Reaksiyada Dövlət İdarəetməsi: Praktik Nümunə

reaksiya
dövlət idarəçiliyi
kontekst api
Reaksiyada Dövlət İdarəetməsi: Praktik Nümunə cover image

React, bir çox tərtibatçılar üçün dinamik müştəri tərəfi proqramlar yaratmaq üçün əsas çərçivədir. Bu proqramların dinamik təbiəti müştəri tərəfində mümkün olan çeviklik və genişləndirilmiş imkanlar və funksiyalar siyahısından irəli gəlir ki, bu da tərtibatçılara bir neçə saniyə ərzində brauzerə yüklənən tam hüquqlu proqramlar yaratmağa imkan verir. statik veb günlərində mümkün (və ya çox çətin).

İmkanların bu genişlənməsi ilə dövlətin idarə edilməsi konsepsiyası meydana çıxdı, çünki müştəri tərəfi tətbiqlərdə mürəkkəblik artdıqca, yerli dövlətin saxlanmasına ehtiyac düzgün idarə edilmədikdə və miqyaslılıq nəzərə alınmaqla düşünülmədikdə, özlüyündə bir darboğaz halına gəlir.

Bu məsələ müxtəlif yanaşmalardan sonra və müxtəlif alt problem dəstlərinə diqqət yetirməklə bir çox çərçivələr tərəfindən həll edilmişdir, buna görə də hər bir tətbiqin ehtiyaclarını qiymətləndirmək və bunlardan sonra düzgün yanaşmadan istifadə etmək üçün seçim çərçivəsinin ekosistemi haqqında yüksək səviyyədə anlayışa sahib olmaq vacibdir. ölçülər. Bu məqalə sizə dövlət idarəetməsi ilə bağlı ümumi problemlər haqqında qısa məlumat verəcək və ona cavab olaraq müxtəlif yanaşmaları (useState, Context API) təqdim etməyə çalışacaq. Bu məqalə bir çox həllər təqdim etsə də, yalnız daha kiçik miqyasda problemlərə diqqət yetirəcək, biz növbəti məqalələrdə daha təkmil mövzuları əhatə edəcəyik.

Doğrulama İş axını

Məqalədə nümayiş etdirilən kodu burada tapa bilərsiniz.

Canlı önizləmə linkinə buradan daxil olmaq olar.

React tətbiqi üçün autentifikasiya prosesini həyata keçirdiyimiz hadisəni nəzərdən keçirək.

User Login

Yuxarıdakı GIF-də göstərildiyi kimi, istifadəçilərə etimadnamələrdən istifadə edərək tətbiqimizə daxil olmağa və ya qeydiyyatdan keçməyə icazə vermək istəyirik. Etibarlı etimadnamələr təqdim olunarsa, istifadəçi daxil olacaq, proqram avtomatik olaraq ana səhifəyə keçəcək və istifadəçi proqramdan istifadə etməyə davam edə bilər.

Eynilə, əgər istifadəçi çıxış edərsə, giriş səhifəsinin resursları girişin arxasında qorunacaq, giriş səhifəsi istifadəçinin əldə edə biləcəyi yeganə səhifə olacaq.

Tətbiq baxımından bu iş axınını düşünsək, Tətbiq adlı əsas komponentimiz olacaq, Tətbiq komponenti istifadəçini iki səhifədən birinə yönləndirəcək: Ev və ya Giriş, istifadəçinin cari vəziyyəti (giriş, çıxış) hansını diktə edəcək istifadəçinin yönləndirildiyi səhifə, istifadəçinin cari vəziyyətindəki dəyişiklik (məsələn, daxil olandan çıxışa keçmək) müvafiq səhifəyə ani yönləndirməyə səbəb olmalıdır.

State

Yuxarıdakı təsvirdə göstərildiyi kimi, biz Tətbiq komponentinin cari vəziyyəti nəzərə almasını və həmin cari vəziyyətə əsasən iki səhifədən yalnız birini – Ev və ya Girişdən birini göstərməsini istəyirik.

Əgər istifadəçi null olarsa, bu o deməkdir ki, bizdə autentifikasiya olunmuş istifadəçi yoxdur, ona görə də biz avtomatik olaraq giriş səhifəsinə keçirik və şərti renderdən istifadə edərək əsas səhifəni qoruyuruq. Əgər istifadəçi varsa, biz bunun əksini edirik.

İndi nəyin həyata keçirilməli olduğunu yaxşı başa düşdük, gəlin bir neçə variantı araşdıraq, lakin əvvəlcə React layihəmizi quraq,

Layihə repoda frontend tərəfini həyata keçirmək üçün istifadə edəcəyimiz nümunə arxa proqram tətbiqi var (burada əsas diqqət yetirilmədiyi üçün ona daxil olmayacağıq, lakin kod qəsdən sadə saxlanılıb ki, onunla çətinlik çəkməyəcəksiniz. )

Aşağıdakı səhifələri və komponentləri yaratmaqla başlayırıq:

  • Əsas Səhifə

  • Giriş səhifəsi

  • Edit İstifadəçi Səhifəsi

  • Navbar Komponenti

  • UserDropdown Komponent

Çoxsaylı səhifələri olan React tətbiqi düzgün naviqasiya tələb edir, bunun üçün biz qlobal brauzer yönləndirici kontekstini yaratmaq və müxtəlif React marşrutlarını qeydiyyatdan keçirmək üçün react-router-dom-dan istifadə edə bilərik.


yarn add react-router-dom

Biz bilirik ki, bir çox oxucu dərsliklərlə yanaşı izləməyi üstün tutur, buna görə də sizi sürətləndirmək üçün başlanğıc şablonu buradadır. Bu başlanğıc filial əvvəlcədən təyin edilmiş TailwindCSS JSX komponentləri üçün DaisyUI-dən istifadə edir. Buraya bütün komponentlər, səhifələr və artıq quraşdırılmış marşrutlaşdırıcı daxildir. Bu təlimatla birlikdə izləməyi, sadə addımlardan sonra bütün auth axınını özünüz qurmağı düşünürsünüzsə, əvvəlcə deponu çəngəlləməklə başlayın. Anbarı bağladıqdan sonra onu klonlayın və burada başlayınbranch:-dan başlayın.


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

Başlanğıc budağını çəkdikdən sonra:

  • Tercih etdiyiniz kod redaktoru ilə layihəni açın

  • Kataloqu frontend/ olaraq dəyişdirin

  • Asılılıqları quraşdırın: iplik

  • İnkişaf serverini işə salın: yarn dev·

Ön baxış bu kimi görünməlidir:

Changing user name

Navbar-da göstərilən ad – yuxarı sağ tərəf – əsas Tətbiq komponentində müəyyən edilmiş vəziyyət dəyişənidir. Eyni dəyişən həm Navbar, həm də Əsas səhifəyə ötürülür. Yuxarıda istifadə olunan sadə forma əslində EditPage komponentindən “ad” vəziyyət dəyişənini yeniləyir.

Aşağıda təqdim olunan iki yanaşma icranın təfərrüatlarına daxil olacaq:

İlk yanaşma: istifadə vəziyyəti

useState()

useState ən çox istifadə olunan React qarmaqlarından biridir, o, sizə React Functional komponentində vəziyyət yaratmağa və mutasiya etməyə imkan verir. UseState komponentinin həqiqətən sadə tətbiqi var və istifadəsi asandır: yeni vəziyyət yaratmaq üçün vəziyyətinizin ilkin dəyəri ilə useState-ə zəng etməlisiniz və useState qarmağı iki dəyişəndən ibarət massivi qaytaracaq: birincisi vəziyyətdir. vəziyyətinizə istinad etmək üçün istifadə edə biləcəyiniz dəyişən, ikincisi isə vəziyyətin dəyərini dəyişdirmək üçün istifadə etdiyiniz funksiya: olduqca sadədir.

Bunu hərəkətdə görsək necə olar? Navbar-da göstərilən ad – yuxarı sağ tərəf – əsas Tətbiq komponentində müəyyən edilmiş vəziyyət dəyişənidir. Eyni dəyişən həm Navbar, həm də Əsas səhifəyə ötürülür. Yuxarıda istifadə olunan sadə forma əslində EditPage komponentindən “ad” vəziyyət dəyişənini yeniləyir. Aşağı xətt belədir: useState ilkin vəziyyəti parametr kimi qəbul edən və iki dəyəri saxlayan iki dəyişəni, ilkin vəziyyəti ehtiva edən vəziyyət dəyişənini və eyni vəziyyət dəyişəni üçün təyinedici funksiyanı qaytaran əsas çəngəldir.

Gəlin onu parçalayaq və ilk növbədə bunun necə həyata keçirildiyini görək.

  1. “Ad” vəziyyət dəyişəninin yaradılması:

./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 (...)};

Rekvizit

Rektivlər reaksiya komponentinin əsas tikinti bloklarından biridir, konseptual olaraq, əgər siz React funksional komponentini Javascript funksiyası kimi düşünürsünüzsə, o zaman rekvizitlər funksiya parametrlərindən çox deyil, rekvizitləri və useState çəngəlini birləşdirərək sizə möhkəm çərçivə təklif edə bilər. sadə React tətbiqi üzərində vəziyyəti idarə etmək üçün.

Reaksiya rekvizitləri xüsusi komponentlərə atribut kimi ötürülür. Rekvizit kimi ötürülən atributlar arqument kimi qəbul edildikdə rekvizit obyektindən buna bənzər şəkildə destrukturizasiya edilə bilər:

Keçid rekvizitləri

<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>

Rekvizitlər normal funksiya arqumentlərinə bənzər funksional komponent daxilində qəbul edilə və istifadə edilə bilər. “Ad” Home komponentinə dayaq kimi ötürüldüyü üçün biz onu eyni komponentdə göstərə bilərik. Aşağıdakı misalda biz rekvizit obyektindən ad xassəsini çıxarmaq üçün dağıdıcı sintaksisdən istifadə edərək ötürülən propı qəbul edirik.

Rekvizitlərin qəbulu

./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 İpucu

Brauzerin konsolunu açın və vəziyyət dəyişdikdə “ad” rekvizitindən istifadə edən bütün komponentlərin necə yenidən göstərildiyinə diqqət yetirin. Vəziyyət dəyişəni ilə manipulyasiya edərkən, React növbəti vəziyyəti saxlayacaq, komponentinizi yeni dəyərlərlə yenidən göstərəcək və UI-ni yeniləyəcək.

Components Re-rendering

Dövlət Dezavantajlarından istifadə edin

Rekvizit-Qazma

Rekvizitlərin qazılması komponentlər toplusunun əsas komponent tərəfindən təmin edilən müəyyən rekvizitlərə ehtiyac duyduğu komponentlərin iyerarxiyasına istinad etmək üçün bir termindir, təcrübəsiz tərtibatçının adətən istifadə etdiyi ümumi həll yolu bu rekvizitləri bütün komponentlər zənciri boyunca ötürməkdir. yanaşma ondan ibarətdir ki, bu rekvizitlərdən hər hansı birində dəyişiklik bütün komponentlər zəncirini yenidən göstərməyə təkan verəcək, bu lazımsız renderlər nəticəsində bütün tətbiqi effektiv şəkildə yavaşlatacaq, zəncirin ortasında bu rekvizitləri tələb etməyən komponentlər rekvizitlərin ötürülməsi üçün vasitə kimi çıxış edir.

Nümunə:

  • UseState() çəngəlindən istifadə edərək əsas Tətbiq komponentində vəziyyət dəyişəni müəyyən edilmişdir

  • Navbar komponentinə ad dəstəyi ötürüldü

  • Eyni dayaq Navbar-da qəbul edildi və bir daha UserDropdown komponentinə dayaq kimi keçdi

  • UserDropdown dayağı qəbul edən sonuncu uşaq elementdir.

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>
    </>
  );
}

Təsəvvür edin ki, eyni vəziyyətdən keçən və göstərən müxtəlif komponent təbəqələri olan React tətbiqini saxlamaq nə qədər çətindir.

Artan mürəkkəblik və kod keyfiyyəti

Reaksiya tətbiqində dövlət idarəçiliyinin yeganə vasitəsi kimi useState və rekvizitlərin istifadəsi ilə kod bazası sürətlə mürəkkəbləşə bilər, bir-birinin dublikatları ola bilən, müxtəlif fayllara səpələnmiş onlarla və yüzlərlə vəziyyət dəyişənlərini idarə etməli olur. komponentlər olduqca qorxulu ola bilər, verilmiş vəziyyət dəyişəninə edilən hər hansı dəyişiklik artıq yavaş olan tətbiqdə hər hansı potensial əlavə renderin qarşısını almaq üçün komponentlər arasında asılılıqların diqqətlə nəzərdən keçirilməsini tələb edəcək.

İkinci yanaşma: Kontekst API

Context API, React-in dövlət idarəçiliyi üçün yalnız rekvizit və useState istifadəsinin çatışmazlıqlarını həll etmək cəhdidir, xüsusən də kontekst API bütün komponent ağacından rekvizitlərin ötürülməsi zərurəti ilə bağlı əvvəllər qeyd olunan məsələyə cavab olaraq gəlir. Kontekstdən istifadə etməklə, siz qlobal hesab etdiyiniz məlumat üçün vəziyyəti təyin edə və komponent ağacındakı istənilən nöqtədən onun vəziyyətinə daxil ola bilərsiniz: daha dirək qazmağa ehtiyac yoxdur.

Qeyd etmək vacibdir ki, kontekst API ilkin olaraq qlobal məlumat mübadiləsi problemini, UI mövzuları kimi məlumatları, istifadə halımız olan autentifikasiya məlumatını, dilləri və sair) paylaşılmalı olan digər məlumat növləri üçün nəzərdə tutulmuşdur. birdən çox komponent arasında, lakin bütün tətbiqlər üçün mütləq qlobal deyil, kontekst ən yaxşı seçim olmaya bilər, istifadə vəziyyətindən asılı olaraq, siz komponent tərkibi kimi digər texnikaları nəzərdən keçirə bilərsiniz. /composition-vs-inheritance.html) bu məqalənin əhatə dairəsi xaricindədir.

Kontekstə keçid

Auth kontekstinin yaradılması

createContext sadədir, o, yeni kontekst dəyişəni yaradır, tək isteğe bağlı parametri qəbul edir: kontekst dəyişəninin standart dəyəri.

Gəlin bunu hərəkətdə görək, əvvəlcə yeni “kontekstlər” qovluğu və onun içərisində yeni “Auth.jsx” faylı yaradın. Yeni kontekst yaratmaq üçün createContext() funksiyasını işə salmalı, qaytarılan dəyəri daha sonra ixrac olunacaq Auth dəyişəninə təyin etməliyik:

./src/contexts/Auth.jsx

import { createContext } from "react";

export const Auth = createContext();

Doğrulama kontekstini təmin edin

İndi biz əvvəllər yaratdığımız "Auth" kontekst dəyişənini ifşa etməliyik, buna nail olmaq üçün kontekst provayderindən istifadə edirik, kontekst provayderi "dəyər" propuna malik komponentdir, biz bu propdan dəyəri paylaşmaq üçün istifadə edə bilərik - ad – komponent ağacında, komponent ağacını provayder komponenti ilə bükməklə biz həmin dayağı hər bir uşaq komponentə ayrıca ötürməyə ehtiyac olmadan həmin dəyəri komponent ağacının istənilən yerindən əlçatan edirik.

Doğrulama nümunəmizdə istifadəçi obyektini saxlamaq üçün dəyişənə və həmin vəziyyət dəyişənini idarə etmək üçün bir növ təyinediciyə ehtiyacımız var, bu useState üçün mükəmməl istifadə halıdır. Kontekstdən istifadə edərkən, təmin etmək istədiyiniz məlumatları təyin etdiyinizə və həmin məlumatları – bizim nümunəmizdəki istifadəçini – içəridə yerləşdirilmiş bütün komponent ağacına ötürdüyünüzə əmin olmalısınız, ona görə də provayder komponentinin daxilində yeni vəziyyət dəyişəni istifadəçisi təyin edin və nəhayət, provayderin komponent ağacına təqdim edəcəyi dəyər kimi massivin içinə həm user, həm də setUser ötürürük:

./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>;
};

Bizim edə biləcəyimiz başqa bir şey "ad" vəziyyəti dəyişənimizi əsas proqram komponentindən Auth kontekstinə köçürmək və onu iç-içə komponentlərə təqdim etməkdir:

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>;
};

İndi qalan şey tətbiqimizi yenicə ixrac etdiyimiz eyni AuthProvider komponentinə yerləşdirməkdir.

./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>
);

Uşaq dayaqlarını Auth.Provider daxilində göstərdiyimizə görə, AuthProvider komponentinin daxilində yerləşdirilmiş bütün elementlər indi Auth.Provider-ə verdiyimiz dəyər dayaqlarını istehlak edə bilir. Bu, çaşqın görünə bilər, lakin onunla sınaqdan keçirdikdən sonra qlobal - Kontekst - vəziyyəti təmin etməyə və istehlak etməyə çalışın. Axı, bu, yalnız Kontekst API ilə sınaqdan keçirdikdən sonra mənə mənalı gəldi.

Doğrulama kontekstinin istehlakı

Son addım sadədir, biz "Auth" kontekst provayderinin təqdim etdiyi dəyərə daxil olmaq üçün "useContext" kontekst çəngəlindən istifadə edirik, bizim vəziyyətimizdə istifadəçi və setUser olan massivdir, aşağıdakı kodda biz edə bilərik Navbar daxilində Auth kontekstini istehlak etmək üçün useContext istifadə edin. Bu, yalnız Navbar-ın Tətbiq komponentinin içərisində yerləşdiyinə görə mümkündür və AuthProvider Tətbiq komponentinin ətrafına sarıldığı üçün dəyər dayağı yalnız useContext çəngəlindən istifadə etməklə istehlak edilə bilər. Başqa bir zəhmli alət React, qlobal olaraq əldə edilə bilən və həmçinin hər hansı bir istehlakçı komponenti tərəfindən idarə oluna bilən istənilən məlumatları idarə etmək üçün qutudan kənar təmin edir.

./src/components/Navbar.jsx

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

 return (...)};

Navbar() funksional komponentində artıq heç bir rekvizit qəbul etmədiyimizə diqqət yetirin. Əvəzində Auth kontekstini istehlak etmək üçün useContext(Auth) istifadə edirik, həm ad, həm də setName götürürük. Bu həm də o deməkdir ki, biz artıq dirəkləri Navbar-a ötürməməliyik:

./src/App.jsx

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

Doğrulama kontekstinin yenilənməsi

“Ad” vəziyyət dəyişənini manipulyasiya etmək üçün təqdim edilmiş setName funksiyasından da istifadə edə bilərik:

./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() çəngəlini təqdim edirik

Əvvəlki nümunədə vəziyyətimizi komponent ağacında idarə etmək və paylaşmaq üçün kontekst API-dən istifadə etdik, bəlkə də məntiqimizin əsası kimi hələ də useState-dən istifadə etdiyimizi görmüsünüz və dövlətimiz hələ də sadə obyektdir. bu nöqtədə, lakin autentifikasiya axınımızın imkanlarını genişləndirmək istəsək, şübhəsiz ki, hazırda daxil olmuş istifadəçinin e-poçtundan daha çoxunu saxlamalı olacağıq və burada əvvəllər daxil etdiyimiz məhdudiyyətlərə qayıdırıq. mürəkkəb vəziyyətlə useState-dən istifadə, xoşbəxtlikdən, React mürəkkəb vəziyyəti idarə etmək üçün useState-ə alternativ təqdim etməklə bu problemi həll edir: useReducer daxil edin.

useReducer-i useState-in ümumiləşdirilmiş versiyası kimi düşünmək olar, o, iki parametr alır: reduktor funksiyası və ilkin vəziyyət.

İlkin vəziyyət üçün qeyd etmək üçün maraqlı bir şey yoxdur, sehr reduktor funksiyasının daxilində baş verir: o, baş verən hərəkət növünü yoxlayır və bu hərəkətdən asılı olaraq reduktor vəziyyətə hansı yeniləmələrin tətbiq ediləcəyini müəyyənləşdirəcək və onun yeni dəyərini qaytaracaq. .

Aşağıdakı koda baxsaq, reduktor funksiyasının iki mümkün hərəkət növü var:

  • "LOGIN": bu halda istifadəçi vəziyyəti əməliyyat yükü daxilində təqdim edilən yeni istifadəçi etimadnaməsi ilə yenilənəcək.

  • "ÇIKIŞ": bu halda istifadəçi vəziyyəti yerli yaddaşdan silinəcək və sıfıra qaytarılacaq.

Qeyd etmək vacibdir ki, fəaliyyət obyekti həm hansı məntiqin tətbiq olunacağını müəyyən edən növ sahəsini, həm də həmin məntiqi tətbiq etmək üçün zəruri olan məlumatları təmin etmək üçün əlavə faydalı yükləmə sahəsini ehtiva edir.

Nəhayət, useReducer qarmağı cari vəziyyəti və reduktora hərəkət ötürmək üçün istifadə etdiyimiz göndərmə funksiyasını qaytarır.

Məntiqin qalan hissəsi üçün əvvəlki nümunə ilə eynidir:

./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>
  );
};

setState təyinedici funksiyasından istifadə etmək əvəzinə hərəkətlərin göndərilməsi – məsələn: setName –

Bayaq qeyd etdiyimiz kimi, reduktora hərəkət ötürmək üçün göndərmə funksiyasından istifadə edirik, aşağıdakı kodda LOGIN əməliyyatına başlayırıq və istifadəçi e-poçtunu faydalı yük kimi təqdim edirik, indi istifadəçi vəziyyəti yenilənəcək və bu dəyişiklik işə salınacaq. istifadəçi vəziyyətinə abunə olan bütün komponentlərin yenidən göstərilməsi. Qeyd etmək vacibdir ki, yenidən göstərmə yalnız vəziyyətdə faktiki dəyişiklik baş verdikdə işə salınacaq, reduktor eyni əvvəlki vəziyyəti qaytararsa, heç bir yenidən göstərilməyəcək.

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 (...)};

İstifadəçi Girişi

JWT Local storage

Pro İpucu

Uğurlu girişdən sonra aldığımız istifadəçi obyektinin indi localStorage-də necə saxlandığına diqqət yetirin.

Giriş üçün xüsusi qarmaq

İndi useReducer-i yaxşı idarə etdiyimizə görə, biz giriş və çıxış məntiqimizi öz ayrıca fərdi qarmaqlarına əlavə edə bilərik, Giriş çəngəlinə bir zənglə, giriş marşrutuna API çağırışını idarə edə, yeni istifadəçini əldə edə bilərik. etimadnaməsini və onları yerli yaddaşda saxlayın, istifadəçi vəziyyətini yeniləmək üçün LOGIN zəngi göndərin, bütün bunlar səhvlərin həlli ilə məşğul olarkən:

./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 };
};

Qeyd: oxucular arasında daha qabaqcıl Reaksiya istifadəçiləri üçün, istifadəçi etimadnamələrini əldə etmək üçün useReducer-in tənbəl işə salma xüsusiyyətindən niyə istifadə etmədiyimizlə maraqlana bilərsiniz, useReducer init funksiyası adlanan üçüncü isteğe bağlı parametri qəbul edir, bu funksiya belə hallarda istifadə olunur. dövlətin ilkin dəyərini əldə etməzdən əvvəl bəzi məntiq tətbiq etməliyik, bunu seçməməyimizin səbəbi sadə narahatlıqların ayrılması məsələsidir, kodu bu şəkildə başa düşmək daha sadədir və nəticədə saxlamaq daha sadədir .

Giriş Səhifəsi

Giriş funksiyasını çıxarmaq üçün useLogin() çəngəlindən istifadə etdikdən və istifadəçi tərəfindən təqdim olunan etimadnamə ilə giriş funksiyasını işə saldıqdan sonra Giriş səhifəmizin yuxarı hissəsi belə görünür:

// ... ... //
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 (...)
// ... ... //

İstifadəçi formanı təqdim etdikdə Göndər funksiyasını da deaktiv edirik:

<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>

Və backendimizdən aldığımız hər hansı autentifikasiya xətalarını göstərmək:

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

Rendering Errors

İstifadəçi vəziyyətinin saxlanması

Siz maraqlana bilərsiniz ki, biz nə üçün istifadəçi obyektini localStorage-də saxlamalıyıq, sadə dillə desək, işarənin müddəti bitmədikcə istifadəçini daxil olmuş saxlamaq istəyirik. LocalStorage-dən istifadə nümunəmizdə olduğu kimi JSON bitlərini saxlamaq üçün əla yoldur. Daxil olduqdan sonra səhifəni yeniləsəniz, vəziyyətin necə silindiyinə diqqət yetirin. Bu, localStorage-də saxlanılan istifadəçi obyektimizin olub-olmadığını yoxlamaq üçün useEffect çəngəlindən istifadə etməklə asanlıqla həll edilə bilər, əgər varsa, biz istifadəçiyə avtomatik daxil oluruq:

// ... ... //
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>
  );
};

Çıxış üçün xüsusi qarmaqlar

Eyni şey Çıxış çəngəlinə də aiddir, burada cari istifadəçi etimadnaməsini həm dövlətdən, həm də yerli yaddaşdan silmək üçün ÇIXIŞ əməliyyatını göndəririk:

./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 };
};

İstifadəçi çıxışı

İstifadəçidən çıxmaq üçün UserDropdown.jsx-də olan Çıxış düyməsinə klik hadisəsi əlavə edək və onu müvafiq qaydada idarə edək:

./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

Reaksiya marşrutlarının qorunması

Tətbiqimizin həyata keçirilməsində son addım, istifadəçi naviqasiyasını idarə etmək üçün qlobal istifadəçi vəziyyətindən istifadə etməkdir, hansı davranışa nail olmağımız barədə tez xatırlatma: əvvəlcə istifadəçi giriş səhifəsi ilə qarşılanır, bu andan istifadəçi yalnız ana səhifəyə daxil ola bilər. Uğurlu girişdən sonra eyni şəkildə istifadəçi çıxışdan sonra giriş səhifəsinə yönləndiriləcək.

Biz buna react-router-dom kitabxanasının köməyi ilə 2 marşrut təyin etməklə nail oluruq: “/” və “/login”, qlobal auth vəziyyətindən istifadə edərək hər marşrutda hansı komponentin göstərilməsinə nəzarət edirik, null olaraq qiymətləndirilən autentifikasiya təsdiqlənməmiş istifadəçini təmsil edir və əksinə:

./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;

Recap Diaqram

Diagram

Ümumiləşdirmə

Bu yazıda biz identifikasiya iş prosesi üçün dövlət idarəçiliyinin həyata keçirilməsinin sadə, lakin çox yayılmış istifadə halını həll etməyə çalışdıq, müxtəlif yanaşmaları, hər birinin arxasında duran əsasları və onların mübadilələrini nəzərdən keçirdik. Müştəri tərəfi çərçivələrində və xüsusən React-də dövlət idarəçiliyi frontend icmasında ən çox danışılan mövzulardan biridir, çünki o, tətbiqinizin performansını və miqyasını artıra və ya poza bilər. Bu dövlət idarəçiliyi məsələsini həll etməyə çalışan müxtəlif texnikaların, nümunələrin, kitabxanaların və vasitələrin çoxluğu hədsizdir, bizim məqsədimiz sizə təcrübələr haqqında möhkəm bir anlayış vermək idi ki, siz bunu öz tətbiqinizdə tətbiq edə biləsiniz. daha mürəkkəb tətbiqlərdə dövlət idarəetmə üsulları və nümunələri, React-də miqyaslana bilən dövlət idarəçiliyi üçün reduxa girdiyimiz növbəti məqaləmizə baxın.

Tezliklə

ContextAPI vs Redux Toolbar

Redux, Redux alət dəstindən əvvəl cəmiyyətdə uzun illər qəbul edildi, əslində RTK yeni tətbiqlərdə redux dövlət idarəçiliyini yükləmək üçün başlanğıc şablon kimi təqdim edildi (onun ilkin adı 2019-cu ilin oktyabrında "redux-starter-kit" idi), baxmayaraq ki, bu gün Redux xidmətçiləri və icma arasında ümumi konsensus var ki, Redux alət dəsti redux ilə işləmək üçün etibarlı yoldur.RTX istifadəni asanlaşdıran bir çox Redux məntiqini mücərrəd edir, daha az təfərrüatlıdır və tərtibatçıları həvəsləndirir. ən yaxşı təcrübələrə əməl edin, ikisi arasındakı əsas fərq ondan ibarətdir ki, Redux qeyri-fikirli olmaq üçün qurulmuşdur, minimal API təmin edir və tərtibatçıların ümumi tapşırıqlar üçün öz kitabxanalarını yazaraq və kod strukturu ilə məşğul olaraq ağır işlərin çoxunu görməsini gözləyir, bu, yavaş inkişaf vaxtı və qarışıq kodla nəticələndi, Redux alət dəsti tərtibatçıların ümumi tələlərə düşməsinin qarşısını alan əlavə abstraksiya təbəqəsi kimi əlavə edildi, daha çox məlumat və onun idarəçilərinin əsaslandırmaları üçün rəsmi sənədlərə baxın burada.


Career Services background pattern

Karyera Xidmətləri

Contact Section background image

Əlaqə saxlayaq

Code Labs Academy © 2024 Bütün hüquqlar qorunur.