Реакттагы мамлекеттик башкаруу: Практикалык мисал

реакция
мамлекеттик башкаруу
контекст api
Реакттагы мамлекеттик башкаруу: Практикалык мисал cover image

React - бул көптөгөн иштеп чыгуучулар үчүн динамикалык кардар тиркемелерин түзүү үчүн негизги алкак. Бул тиркемелердин динамикалык мүнөзү кардар тарабында мүмкүн болгон мүмкүнчүлүктөрдүн жана функциялардын ийкемдүүлүгүнөн жана кеңейтилген тизмесинен келип чыгат, бул иштеп чыгуучуларга бир нече секунданын ичинде браузерде жүктөлгөн толук кандуу тиркемелерди түзүүгө мүмкүндүк берди, бул мындай эрдик. мүмкүн (же өтө түйшүктүү) статикалык желе күндөрү.

Мүмкүнчүлүктөрдүн мындай кеңейиши менен мамлекетти башкаруу концепциясы келип чыкты, анткени кардар тараптагы тиркемелерде татаалдык өскөн сайын, жергиликтүү штатты сактоо муктаждыгы, эгерде туура иштетилбесе жана масштабдуулукту эске алуу менен ойлонулбаса, өзүнөн өзү эле бөгөт болуп калат.

Бул маселе ар кандай ыкмалардан кийин жана ар кандай субпроблемалар топтомуна басым жасоо менен көптөгөн алкактар ​​менен чечилген, ошондуктан ар бир тиркеменин муктаждыктарын баалоо жана аларга ылайык туура мамилени колдонуу үчүн тандоо алкагындагы экосистеманы жогорку деңгээлде түшүнүү маанилүү. метрикалар. Бул макала сизге мамлекеттик башкаруунун жалпы көйгөйлөрүнө кыскача сереп салып, ага жооп катары ар кандай ыкмаларды (useState, Context API) киргизүүгө аракет кылат. Бул макалада бир нече чечимдерди сунуштайт, бирок ал кичирээк масштабдагы көйгөйлөргө гана көңүл бурат, биз алдыдагы макалаларда өркүндөтүлгөн темаларды камтыйт.

Аутентификация иш процесси

Макалада көрсөтүлгөн кодду бул жерден тапса болот.

Алдын ала көрүү шилтемесин бул жерден алса болот.

React тиркемеси үчүн аутентификация процессин ишке ашырган учурду карап көрөлү.

User Login

Жогорудагы GIFте көрсөтүлгөндөй, биз колдонуучуларга эсептик дайындарды колдонуу менен биздин тиркемеге кирүүгө же катталууга уруксат бергибиз келет. Эгер жарактуу эсептик маалыматтар берилген болсо, колдонуучу кирет, колдонмо автоматтык түрдө башкы бетке өтөт жана колдонуучу тиркемени колдонууну уланта алат.

Ошо сыяктуу эле, эгерде колдонуучу чыгып кетсе, үй баракчасынын ресурстары логиндин артында корголот, кирүү баракчасы колдонуучуга жеткиликтүү болгон жалгыз барак болот.

Бул иш процессин ишке ашыруу жагынан ойлонсок, бизде App аттуу негизги компонент болот, Колдонмо компоненти колдонуучуну эки барактын бирине багыттайт: Үй же Кирүү, колдонуучунун учурдагы абалы (кирилген, чыккан) кайсынысын аныктайт Колдонуучу багытталган бетке, колдонуучунун учурдагы абалынын өзгөрүшү (мисалы, киргенден чыгууга өтүү) тиешелүү бетке заматта кайра багыттоону козгошу керек.

State

Жогорудагы сүрөттө көрсөтүлгөндөй, биз Колдонмонун компоненти учурдагы абалды эске алып, ошол учурдагы абалдын негизинде эки барактын бирин гана - Үй же Кирүү - көрсөтүшүн каалайбыз.

Эгерде колдонуучу нөл болсо, анда бизде аныктыгы текшерилген колдонуучу жок дегенди билдирет, андыктан биз кирүү барагына автоматтык түрдө өтөбүз жана шарттуу көрсөтүү аркылуу башкы бетти коргойбуз. Колдонуучу бар болсо, биз тескерисинче кылабыз.

Эми биз эмнени ишке ашыруу керектигин жакшы түшүнгөнүбүздөн кийин, келгиле, бир нече варианттарды изилдеп көрөлү, бирок адегенде биздин React долбоорун түзөлү,

Долбоордун репосунда биз алдыңкы тарапты ишке ашыруу үчүн колдоно турган үлгү тиркеме камтылган (биз ага кирбейбиз, анткени бул жерде негизги көңүл бурулбайт, бирок код атайылап жөнөкөй сакталган, андыктан сиз аны менен кыйналбайсыз. )

Биз төмөнкү барактарды жана компоненттерди түзүү менен баштайбыз:

  • Башкы бет

  • Кирүү баракчасы

  • EditUser Page

  • Navbar компоненти

  • UserDropdown компоненти

Бир нече барактары бар React тиркемеси туура навигацияны талап кылат, ал үчүн биз react-router-domду глобалдык серепчи роутер контекстин түзүү жана ар кандай React маршруттарын каттоо үчүн колдоно алабыз.


yarn add react-router-dom

Көптөгөн окурмандар окуу куралдары менен бирге ээрчүүнү каалаарын билебиз, андыктан бул жерде сизди тездетүү үчүн баштапкы шаблон. Бул баштапкы бөлүм DaisyUIди алдын ала аныкталган TailwindCSS JSX компоненттери үчүн колдонот. Ал бардык компоненттерди, барактарды жана буга чейин орнотулган роутерди камтыйт. Эгер сиз бул окуу куралына кошулуп, түз кадамдарды аткарып, бүтүндөй аутентификация агымын өз алдынча түзүүнү ойлонуп жатсаңыз, адегенде репозиторийди айрыбастан баштаңыз. Репозиторийди айрыгандан кийин, аны клондоңуз жана start-бул жерденbranch: баштап баштаңыз.


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

Башталгыч бутагын тарткандан кийин:

  • Өзүңүз каалаган код редактору менен долбоорду ачыңыз

  • Каталогду frontend/ кылып өзгөртүңүз

  • Көз карандылыкты орнотуу: жип

  • Иштеп чыгуу серверин баштоо: iplik dev·

Алдын ала көрүү төмөнкүдөй болушу керек:

Changing user name

Navbarда көрсөтүлгөн аталыш - жогорку оң жагы - негизги Колдонмонун компонентинде аныкталган абал өзгөрмөсү. Ошол эле өзгөрмө Navbar жана Башкы бетке өткөрүлөт. Жогоруда колдонулган жөнөкөй форма чындыгында EditPage компонентинен "аты" абал өзгөрмөсүн жаңыртат.

Төмөндө берилген эки ыкма ишке ашыруунун деталдарына кирет:

Биринчи мамиле: useState

useState()

useState эң көп колдонулган React илгичтеринин бири, ал React Functional компонентинде абалды түзүүгө жана мутациялоого мүмкүндүк берет. UseState компоненти чындап эле жөнөкөй ишке ашырууга ээ жана колдонууга оңой: жаңы абалды түзүү үчүн, абалыңыздын баштапкы мааниси менен useState чакырышыңыз керек жана useState илгичи эки өзгөрмөлүү массивди кайтарат: биринчиси - абал Сиздин абалыңызга шилтеме жасоо үчүн колдоно турган өзгөрмө, ал эми экинчиси - мамлекеттин маанисин өзгөртүү үчүн колдонгон функция: абдан жөнөкөй.

Муну иш жүзүндө көрөбүзбү? Navbarда көрсөтүлгөн аталыш - жогорку оң жагы - негизги Колдонмонун компонентинде аныкталган абал өзгөрмөсү. Ошол эле өзгөрмө Navbar жана Башкы бетке өткөрүлөт. Жогоруда колдонулган жөнөкөй форма чындыгында EditPage компонентинен "аты" абал өзгөрмөсүн жаңыртат. Төмөнкү сап бул: useState - бул баштапкы абалды параметр катары кабыл алган жана эки мааниге ээ болгон эки өзгөрмөлөрдү, баштапкы абалды камтыган абал өзгөрмөсүн жана ошол эле абал өзгөрмөсү үчүн орнотуучу функцияны кайтарган негизги илгич.

Келгиле, аны талкалап көрөлү жана биринчи кезекте бул кандайча ишке ашырылганын карап көрөлү.

  1. “Аты” абал өзгөрмөсүн түзүү:

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

Пропорциялар

Реактивдүү реквизиттер реакция компонентинин негизги курулуш блокторунун бири болуп саналат, концептуалдык жактан, эгер сиз React функционалдык компонентин Javascript функциясы катары ойлосоңуз, анда реквизиттер функциянын параметрлеринен ашпайт, реквизиттерди жана useState илгичтерин айкалыштыруу сизге бекем негизди сунуштай алат. жөнөкөй React тиркемеси аркылуу абалды башкаруу үчүн.

Реакция реквизиттери ыңгайлаштырылган компоненттердин атрибуттары катары өткөрүлөт. Бута катары берилген атрибуттарды аргумент катары кабыл алууда реквизиттер объектисинен ушуга окшош структурасын бузууга болот:

Өтүү реквизиттери

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

Рекламаларды кадимки функция аргументтерине окшош функционалдык компоненттин ичинде кабыл алып, колдонсо болот. Себеби "ат" Home компонентине таяныч катары берилгендиктен, биз аны ошол эле компонентте көрсөтө алабыз. Төмөнкү мисалда биз реквизиттер объектисинен name касиетин чыгаруу үчүн бузулуучу синтаксистин жардамы менен өткөн таянычты кабыл алып жатабыз.

Буюмдарды кабыл алуу

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

Браузердин консолун ачып, абал өзгөргөндө "аты" тиркемесин колдонгон бардык компоненттер кантип кайра көрсөтүлүп жатканын байкаңыз. Статус өзгөрмөсүн манипуляциялоодо, React кийинки абалды сактап, компонентиңизди жаңы маанилер менен кайра көрсөтөт жана UIди жаңылайт.

Components Re-rendering

Мамлекеттик кемчиликтерди колдонуңуз

Бутактуу бургулоо

Буталарды бургулоо - бул компоненттердин иерархиясына шилтеме берүү термини, анда компоненттердин жыйындысы ата-энелик компонент тарабынан камсыздалган белгилүү бир реквизиттерди талап кылат, тажрыйбасыз иштеп чыгуучу адатта колдонгон жалпы чечмелөө бул реквизиттерди компоненттердин бардык чынжырына өткөрүү болуп саналат. мамиле бул реквизиттердин кайсы биринин өзгөрүшү компоненттердин бүт чынжырын кайра көрсөтүүгө түрткү берет, бул керексиз рендерлердин натыйжасында бүт колдонмону эффективдүү жайлатат, чынжырдын ортосунда бул реквизиттерди талап кылбаган компоненттер реквизиттерди өткөрүп берүү үчүн каражат катары иштешет.

Мисалы:

  • Колдонмонун негизги компонентинде useState() илгичинин жардамы менен абал өзгөрмөсү аныкталган

  • Navbar компонентине ат таяныч өткөрүлдү

  • Ошол эле таяныч Navbarда кабыл алынып, UserDropdown компонентине дагы бир жолу таяныч катары өттү

  • UserDropdown - бул таянычты кабыл алган акыркы бала элемент.

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

Элестетиңиз, React колдонмосун сактап калуу канчалык кыйын экенин, ар кандай катмардагы компоненттердин баары бир эле абалда өтүп, көрсөтүү.

Өсүп жаткан татаалдык жана коддун сапаты

Реактивдүү тиркемеде мамлекеттик башкаруунун жападан жалгыз каражаты катары useState жана реквизиттерди колдонуу менен код базасы тез арада татаалдашып, он же жүздөгөн абал өзгөрмөлөрүн башкарууга туура келет, алар бири-биринин кайталанмалары болушу мүмкүн, ар кандай файлдарга чачыранды жана компоненттери өтө коркунучтуу болушу мүмкүн, берилген абал өзгөрмөсүнө болгон ар кандай өзгөртүү ансыз да жай колдонууда кандайдыр бир мүмкүн болгон кошумча кайра көрсөтүүнү болтурбоо үчүн компоненттердин ортосундагы көз карандылыктарды кылдаттык менен кароону талап кылат.

Экинчи ыкма: Контекст API

Context API - бул React компаниясынын мамлекеттик башкаруу үчүн гана реквизиттерди жана useState колдонуудагы кемчиликтерди чечүү аракети, атап айтканда, контексттик API бардык компонент дарагынан реквизиттерди өткөрүп берүү зарылчылыгы жөнүндө мурда айтылган маселеге жооп катары келет. Контекстти колдонуу менен, сиз глобалдык деп эсептеген маалыматтардын абалын аныктай аласыз жана анын абалына компонент дарагынын каалаган жеринен кире аласыз: мындан ары бургулоо жок.

Контексттик API адегенде глобалдык маалыматтарды бөлүшүү маселесин чечүү үчүн иштелип чыкканын, UI темалары сыяктуу маалыматтарды, биздин колдонуу учурубуз болгон аутентификация маалыматы, тилдер жана башка), бөлүшүлүшү керек болгон башка маалымат түрлөрү үчүн иштелип чыкканын белгилей кетүү маанилүү. бирден ашык компоненттердин арасында, бирок бардык тиркемелер үчүн глобалдуу эмес, контекст эң жакшы вариант болбошу мүмкүн, колдонуу учуруна жараша, компоненттин курамы сыяктуу башка ыкмаларды карап көрсөңүз болот. /composition-vs-inheritance.html) бул макаланын алкагына кирбейт.

Контекстке өтүү

Auth контекстти түзүү

createContext жөнөкөй, ал жаңы контексттик өзгөрмө түзөт, ал бир гана кошумча параметрди алат: контексттик өзгөрмөнүн демейки мааниси.

Келгиле, муну иш жүзүндө карап көрөлү, адегенде жаңы “контексттер” папкасын жана анын ичинде “Auth.jsx” жаңы файлын түзүңүз. Жаңы контекстти түзүү үчүн, биз createContext() функциясын чакырышыбыз керек, кайтарылган маанини кийинки экспорттолуучу жаңы Auth өзгөрмөсүнө дайындашыбыз керек:

./src/contexts/Auth.jsx

import { createContext } from "react";

export const Auth = createContext();

Автордук контекстти бериңиз

Эми биз мурда түзүлгөн "Auth" контексттик өзгөрмөсүн ачып беришибиз керек, ага жетүү үчүн биз контексттик провайдерди колдонобуз, контексттик провайдер "баа" таянычына ээ компонент, биз бул таянычты маанини бөлүшүү үчүн колдоно алабыз - аты – компонент дарагы боюнча, компонент дарагын провайдер компоненти менен ороп, биз бул маанини ар бир бала компонентке өзүнчө өткөрүп берүүнүн зарылдыгы жок, компонент дарагынын ичиндеги каалаган жерден жеткиликтүү кылабыз.

Биздин аутентификация мисалында, колдонуучу объектин кармап туруу үчүн өзгөрмө керек жана ал абал өзгөрмөсүн башкаруу үчүн кандайдыр бир орнотуучу керек, бул useState үчүн эң сонун колдонуу учуру. Контекстти колдонууда, сиз бергиси келген маалыматтарды аныктап, ал маалыматтарды – биздин мисалдагы колдонуучу – ичине уя салынган бардык компонент дарагына өткөрүп жатканыңызды текшеришиңиз керек, андыктан камсыздоочу компоненттин ичинде жаңы абал өзгөрмө колдонуучуну аныктаңыз жана акыры биз массивдин ичине колдонуучуну да, setUserди да провайдер компонент дарагына көрсөтө турган маани катары өткөрөбүз:

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

Биз кыла турган дагы бир нерсе - биздин "ат" абалынын өзгөрмөсүн колдонмонун негизги компонентинен Auth контекстине жылдыруу жана аны уяланган компоненттерге көрсөтүү:

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

Эми биздин колдонмону биз жаңы эле экспорттогон AuthProvider компонентине уя салуу гана калды.

./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 ичинде балдар таянычын көрсөтүп жаткандыктан, AuthProvider компонентинин ичине уя салынган бардык элементтер эми биз Auth.Providerге өткөрүп берген маанилик таянычты колдоно алышат. Бул чаташкандай көрүнүшү мүмкүн, бирок аны менен бир жолу эксперимент кылгандан кийин, глобалдык - Контекст - абалды камсыздап жана колдонууга аракет кылыңыз. Кантсе да, бул Context API менен эксперимент кылгандан кийин гана мага түшүнүктүү болду.

Автордук контекстти керектөө

Акыркы кадам жөнөкөй, биз "Auth" контексттик провайдери берип жаткан мааниге жетүү үчүн "useContext" контексттик илгичти колдонобуз, ал биздин учурда төмөнкү коддо колдонуучу жана setUser камтылган массив болуп саналат. Navbar ичиндеги Auth контекстин керектөө үчүн useContext колдонуңуз. Бул бир гана мүмкүн, анткени Navbar Колдонмонун компонентинин ичине уя салынган жана AuthProvider Колдонмонун компонентинин айланасын ороп алгандыктан, баалуулук таянычын useContext илгичи менен гана колдонууга болот. React дагы бир укмуштуудай куралы бүткүл дүйнөлүк жетүү мүмкүн болгон, ошондой эле каалаган керектөөчү компоненти тарабынан башкарылуучу маалыматтарды башкаруу үчүн кутудан тышкары берет.

./src/components/Navbar.jsx

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

 return (...)};

Navbar() функционалдык компонентинде мындан ары эч кандай буталарды кабыл албай жатканыбызды байкаңыз. Анын ордуна Auth контекстин керектөө үчүн useContext(Auth) колдонуп жатабыз, ат менен setName экөөнү тең кармап жатабыз. Бул мындан ары Навбарга таянычты өткөрүүнүн кереги жок дегенди билдирет:

./src/App.jsx

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

Auth контекстти жаңылоо

Биз берилген setName функциясын "name" абалынын өзгөрмөсүн башкаруу үчүн да колдоно алабыз:

./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() илгичти киргизүү

Мурунку мисалда биз абалыбызды башкаруу жана бөлүшүү үчүн контексттик API колдондук, сиз биздин логиканын негизи катары дагы эле useState колдонуп жатканыбызды байкаган болушуңуз мүмкүн жана бул биздин абалыбыз дагы эле жөнөкөй объект болгондуктан, бул жакшы. Бул учурда, бирок биз аутентификация агымыбыздын мүмкүнчүлүктөрүн кеңейте турган болсок, биз, албетте, учурда кирген колдонуучунун электрондук почтасын гана сакташыбыз керек болот жана ушул жерден биз мурда киргизилген чектөөлөргө кайтып келебиз. татаал абал менен useState колдонуу, бактыга жараша, React татаал абалды башкаруу үчүн useState альтернативасын берүү менен бул маселени чечет: useReducer киргизиңиз.

useReducerди useStateдин жалпыланган версиясы катары кароого болот, ал эки параметрди алат: редуктор функциясы жана баштапкы абал.

Баштапкы абалды белгилей турган кызыктуу эч нерсе жок, сыйкыр редуктор функциясынын ичинде болот: ал болгон аракеттин түрүн текшерет жана ошол аракетке жараша редуктор мамлекетке кандай жаңыртууларды колдонууну аныктайт жана анын жаңы маанисин кайтарат. .

Төмөндөгү кодду карасак, редуктор функциясы эки мүмкүн болгон иш-аракеттердин түрүн камтыйт:

  • "LOGIN": бул учурда колдонуучунун абалы аракеттин пайдалуу жүктөмүнүн ичинде берилген жаңы колдонуучунун эсептик дайындары менен жаңыртылат.

  • "ЧЫГУУ": бул учурда колдонуучунун абалы жергиликтүү сактагычтан алынып салынат жана кайра нөлгө коюлат.

Иш-аракет объектисинде кайсы логиканы колдонуу керектигин аныктаган тип талаасы жана ошол логиканы колдонуу үчүн зарыл болгон маалыматтарды берүү үчүн кошумча пайдалуу жүк талаасы бар экенин белгилей кетүү маанилүү.

Акыр-аягы, useReducer илгичи учурдагы абалды жана редукторго аракетти өткөрүү үчүн колдонгон жөнөтүү функциясын кайтарат.

Калган логика үчүн бул мурунку мисалга окшош:

./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 орнотуучу функциясын колдонуунун ордуна аракеттерди жөнөтүү – мисалы: setName –

Жогоруда айтылгандай, биз редукторго иш-аракетти өткөрүү үчүн жөнөтүү функциясын колдонобуз, төмөнкү коддо биз LOGIN аракетин баштайбыз жана колдонуучунун электрондук почтасын пайдалуу жүк катары беребиз, эми колдонуучунун абалы жаңыртылып, бул өзгөртүү ишке ашат. колдонуучунун абалына жазылган бардык компоненттерди кайра көрсөтүү. Белгилей кетчү нерсе, кайра көрсөтүү абалында иш жүзүндө өзгөрүү болгондо гана иштетилет, эгерде редуктор мурунку эле абалды кайтарса, кайра көрсөтүү болбойт.

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

Колдонуучунун кирүү

JWT Local storage

Pro Tip

Ийгиликтүү киргенден кийин биз алган колдонуучу объекти азыр localStorageде кандайча сакталып калганына көңүл буруңуз.

Кирүү үчүн атайын илгич

Эми биз useReducerди жакшы кармай алганыбыздан кийин, биз кирүү жана чыгуу логикабызды өздөрүнүн өзүнчө ыңгайлаштырылган илгичтерине киргизе алабыз, Логин илгичине бир жолу чалуу менен, биз кирүү маршрутуна API чалуу менен иштей алабыз, жаңы колдонуучуну чыгарып алабыз. эсептик дайындарды жана аларды жергиликтүү сактагычта сактаңыз, колдонуучунун абалын жаңыртуу үчүн LOGIN чалуусун жөнөтүңүз, мунун баары ката менен иштөөдө:

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

Эскертүү: окурмандардын арасында өнүккөн React колдонуучулары үчүн, сиз эмне үчүн колдонуучунун эсептик дайындарын алуу үчүн useReducerдин жалкоо инициализация функциясын колдонгон жокпуз деп ойлонуп жатсаңыз болот, useReducer init функциясы деп аталган үчүнчү кошумча параметрди кабыл алат, бул функция мындай учурларда колдонулат Биз мамлекеттин баштапкы маанисин алуудан мурун кандайдыр бир логиканы колдонушубуз керек, муну тандабаганыбыздын себеби - тынчсызданууларды бөлүүнүн жөнөкөй маселеси, кодду бул жол менен түшүнүү жөнөкөй жана натыйжада сактоо оңой .

Кирүү баракчасы

Кирүү функциясын чыгарып алуу үчүн useLogin() илгичин колдонуп жана колдонуучу тапшырган эсептик дайындар менен кирүү функциясын чакыргандан кийин, биздин Кирүү бетибиздин үстүнкү бөлүгү төмөнкүдөй болот:

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

Колдонуучу форманы тапшырганда Тапшыруу функциясын да өчүрөбүз:

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

Жана биздин серверден алган аутентификация каталарын көрсөтүү:

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

Rendering Errors

Колдонуучунун абалын сактоо

Сиз эмне үчүн колдонуучу объектисин localStorage'де сактоо керек деп ойлонуп жатсаңыз болот, жөнөкөй сөз менен айтканда, биз токендин мөөнөтү бүтө элек колдонуучуну каттоо эсебинде калтыргыбыз келет. localStorage колдонуу биздин мисалдагыдай JSON биттерин сактоонун эң сонун жолу. Киргенден кийин баракты жаңыртып койсоңуз, абал кандайча өчүп калганына көңүл буруңуз. Бул localStorage ичинде сакталган колдонуучу объектиси бар же жок экенин текшерүү үчүн useEffect илгичтин жардамы менен оңой чечилет, эгер бар болсо, биз колдонуучуга автоматтык түрдө киребиз:

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

Чыгуу үчүн атайын илгичтер

Ошол эле нерсе Чыгуу илгичине да тиешелүү, бул жерде биз учурдагы колдонуучунун эсептик дайындарын штаттан жана жергиликтүү сактагычтан алып салуу үчүн ЧЫГУУ аракетин жөнөтөбүз:

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

Колдонуучудан чыгуу

Колдонуучудан чыгуу үчүн UserDropdown.jsx ичинде табылган Чыгуу баскычына чыкылдатуу окуясын кошуп, ага жараша иштетели:

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

Реакция багыттарын коргоо

Биздин тиркемени ишке ашыруудагы акыркы кадам - ​​бул колдонуучунун навигациясын көзөмөлдөө үчүн колдонуучунун глобалдык абалын колдонуу, биз кандай жүрүм-турумга жетишүүбүз керектиги жөнүндө тез эскертүү: адегенде колдонуучуну логин барагы тосуп алат, ошондон баштап колдонуучу башкы бетке гана кире алат. ийгиликтүү киргенден кийин, колдонуучу чыккандан кийин кирүү барагына кайра багытталат.

Биз буга react-router-dom китепканасынын жардамы менен 2 маршрутту аныктоо аркылуу жетишебиз: "/" жана "/login", биз глобалдык аутентификация абалын колдонуу менен ар бир маршрутта кайсы компонентти көрсөтүүнү көзөмөлдөйбүз, нөлгө бааланган аутентификация аутентификацияланбаган колдонуучуну билдирет жана тескерисинче:

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

Кыскача диаграмма

Diagram

Киришүү

Бул макалада биз аутентификациянын иш процесси үчүн мамлекеттик башкарууну ишке ашыруунун жөнөкөй, бирок өтө кеңири таралган учурун чечүүгө аракет кылдык, ар кандай ыкмаларды, ар биринин жүйөсүн жана алардын карама-каршылыктарын карап чыктык. Кардар тараптык алкактарында жана өзгөчө React-те мамлекеттик башкаруу фронттук коомчулукта эң көп талкууланган темалардын бири, анткени ал сиздин колдонмоңуздун иштешин жана масштабдуулугун түзө алат же бузушу мүмкүн. Мамлекеттик башкаруунун бул маселесин чечүүгө аракет кылган ар кандай техникалардын, үлгүлөрдүн, китепканалардын жана куралдардын көптүгү абдан чоң, биздин максат сизге практикалар жөнүндө терең түшүнүк берүү болчу, ошондуктан сиз аны өзүңүздүн колдонмоңузда ишке ашыра аласыз. татаалыраак тиркемелерде мамлекеттик башкаруунун ыкмаларын жана үлгүлөрүн карап чыгыңыз, кийинки макалабызды караңыз, анда биз React'те масштабдуу мамлекеттик башкаруу үчүн кыскартууга киребиз.

Жакында келмекчи

ContextAPI vs Redux Toolkit

Redux инструменттер топтомуна чейин коомчулукта көп жылдар бою кабыл алынган, чындыгында, RTK жаңы тиркемелерде redux мамлекеттик башкаруусун жүктөө үчүн баштапкы шаблон катары киргизилген (анын баштапкы аталышы 2019-жылдын октябрында "redux-starter-kit" болгон), бирок бүгүнкү күндө Redux тейлөөчүлөрү менен коомчулуктун ортосунда жалпы консенсус бар, Redux инструменттери redux.RTX менен иштөөнүн жарактуу жолу болуп саналат, бул Redux логикасынын көп абстракциясын камтыйт, бул аны колдонууну жеңилдетет, бир кыйла азыраак жана иштеп чыгуучуларга үндөйт. эң жакшы тажрыйбаларды колдонуңуз, экөөнүн ортосундагы негизги айырмачылыктар Redux минималдуу API менен камсыз кылуу жана иштеп чыгуучулардан жалпы тапшырмалар үчүн өз китепканаларын жазуу жана код түзүмү менен иштөө аркылуу оор жүктөрдү көтөрүүнү күтүү үчүн курулган. Бул жай иштеп чыгуу убактысына жана башаламан кодго алып келди, Redux инструменталдык комплекти кошумча абстракция катмары катары кошулду, ал иштеп чыгуучулардын жалпы туңгуюктарына түшүп калуусуна жол бербейт, көбүрөөк түшүнүктөрдү жана аны колдоочулардын жүйөсүн [бул жерде] расмий документациядан караңыз (https:/ /redux.js.org/introduction/why-rtk-is-redux-today).


Career Services background pattern

Карьера кызматтары

Contact Section background image

байланышта бололу

Code Labs Academy © 2024 Бардык укуктар корголгон.