You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Web-Dev-For-Beginners/translations/sr/7-bank-project/4-state-management
localizeflow[bot] 6602ddcc6a
chore(i18n): sync translations with latest source changes (chunk 1/1, 291 changes)
7 months ago
..
README.md chore(i18n): sync translations with latest source changes (chunk 1/1, 291 changes) 7 months ago
assignment.md chore(i18n): sync translations with latest source changes (chunk 1/1, 291 changes) 7 months ago

README.md

Направите банкарску апликацију, део 4: Концепти управљања стањем

Шта можете урадити у наредних 5 минута

Пут за брзи почетак за заузете програмере

flowchart LR
    A[⚡ 5 минута] --> B[Дијагностикујте проблеме са стањем]
    B --> C[Креирајте централни објекат стања]
    C --> D[Додајте функцију updateState]
    D --> E[Видите одмах побољшања]
  • Минут 1: Тестирајте тренутни проблем са стањем - пријавите се, освежите страницу, посматрајте одјаву
  • Минут 2: Замените let account = null са let state = { account: null }
  • Минут 3: Креирајте једноставну функцију updateState() за контролисана ажурирања
  • Минут 4: Ажурирајте једну функцију да користи нови образац
  • Минут 5: Тестирајте побољшану предвидљивост и могућност снимања грешака

Брзи дијагностички тест:

// Пре: Расут стање
let account = null; // Изгубљено након освежавања!

// После: Централизовано стање
let state = Object.freeze({ account: null }); // Контролисано и пратљиво!

Зашто је ово важно: За 5 минута ћете доживети трансформацију од хаотичног управљања стањем до предвидивих, лако опструираних образаца. Ово је основа која чини сложене апликације одрживим.

🗺️ Ваш пут учења кроз мајсторство управљања стањем

journey
    title Од расутостa до професионалне архитектуре
    section Дијагностика проблема
      Identify state loss issues: 3: You
      Understand scattered updates: 4: You
      Recognize architecture needs: 6: You
    section Централизовање контроле
      Create unified state object: 5: You
      Implement controlled updates: 7: You
      Add immutable patterns: 8: You
    section Додавање перзистенције
      Implement localStorage: 6: You
      Handle serialization: 7: You
      Create session continuity: 9: You
    section Балансирање свежењe
      Address data staleness: 5: You
      Build refresh systems: 8: You
      Achieve optimal balance: 9: You

Циљ вашег путовања: До краја ове лекције изградићете професионални систем управљања стањем који рукује перзистенцијом, свежином података и предвидивим ажурирањима - исте образце које користе производне апликације.

Пре-лекцијски квиз

Пре-лекцијски квиз

Увод

Управљање стањем је као навигациони систем на свемирском броду Voyager када све ради глатко, готово да не приметите да је ту. Али када нешто пође по злу, постаје разлика између доласка до интерстеларног простора и лутања у космичком празнину. У веб развоју, стање представља све што ваша апликација мора да памти: статус пријаве корисника, податке из форми, историју навигације и привремена стања интерфејса.

Док се ваша банкарска апликација развијала из једноставног формулара за пријаву у софистициранију апликацију, вероватно сте наишли на неке уобичајене изазове. Освежите страницу и корисници се неочекивано одјављују. Затворите прегледач и сав напредак нестаје. Снимање грешке значи претраживање преко више функција које на различите начине мењају исте податке.

Ово нису знакови лошег кода ово су природне растуће боли које се јављају када апликације достигну одређени ниво сложености. Сваки програмер се суочава са овим изазовима док њихове апликације прелазе из „доказа концепта“ у „спремне за производњу“.

У овој лекцији ћемо имплементирати централизовани систем управљања стањем који ће вашу банкарску апликацију трансформисати у поуздану, професионалну апликацију. Научићете како контролисано управљати током података, правилно чувати сесије корисника и створити глатко корисничко искуство које модерне веб апликације захтевају.

Предуслови

Пре него што зароните у концепте управљања стањем, морате имати исправно подешено развојно окружење и постављену основу банкарске апликације. Ова лекција се директно надовезује на концепте и код из претходних делова ове серије.

Уверите се да имате следеће компоненте спремне пре наставка:

Потребна подешавања:

  • Завршите лекцију о дохватању података - ваша апликација треба успешно да учита и прикаже податке о рачуну
  • Инсталирајте Node.js на свом систему за покретање серверске API
  • Покрените локално серверски API да бисте управљали операцијама са подацима рачуна

Тестирање вашег окружења:

Проверите да ли ваш API сервер ради исправно извршавањем ове команде у терминалу:

curl http://localhost:5000/api
# -> треба да врати "Bank API v1.0.0" као резултат

Шта ова команда ради:

  • Слање GET захтева вашем локалном API серверу
  • Тестирање везе и провера одговора сервера
  • Враћање информација о верзији API ако све ради исправно

🧠 Преглед архитектуре управљања стањем

mindmap
  root((Управљање стањем))
    Тренутни проблеми
      Губитак сесије
        Проблеми са освежавањем странице
        Утицај затварања прегледача
        Проблеми ресетовања променљивих
      Расуте измене
        Више тачака измене
        Изазови у дебаговању
        Непредвидиво понашање
      Непотпуна чистка
        Проблеми са статусом одјаве
        Цурење меморије
        Безбедносни ризици
    Централизована решења
      Унифицирани објекат стања
        Један извор истине
        Предвидива структура
        Скалирана основа
      Контролисане измене
        Немутабилни обрасци
        Коришћење Object.freeze
        Промене засноване на функцијама
      Праћење стања
        Управљање историјом
        Видљивост у дебагу
        Ревизија измена
    Стратегије перзистенције
      Интеграција localStorage-а
        Континуитет сесије
        Серијализација у JSON
        Аутоматска синхронизација
      Свеже податке
        Освежавање са сервера
        Руковање застарелим подацима
        Оптимизација баланса
      Оптимизација складиштења
        Минимални подаци
        Фокус на перформансе
        Безбедносне разматрања

Основно правило: Професионално управљање стањем балансира предвидивост, перзистенцију и перформансе за стварање поузданих корисничких искустава која се скалирају од једноставних интеракција до сложених радних токова апликација.


Дијагностика тренутних проблема са стањем

Као што Шерлок Холмс испитује место злочина, морамо сасвим разумети шта се дешава у нашој тренутној имплементацији пре него што решимо мистерију нестајања корисничких сесија.

Извршићемо једноставан експеримент који открива изазове управљања стањем:

🧪 Испробајте овај дијагностички тест:

  1. Пријавите се у вашу банкарску апликацију и идите на контролну таблу
  2. Освежите страницу у прегледачу
  3. Посматрајте шта се догађа са статусом пријаве

Ако вас врати на екран за пријаву, открили сте класичан проблем перзистенције стања. Ово се дешава јер наша тренутна имплементација чува корисничке податке у JavaScript променљивима која се ресетују сваки пут када се страница освежи.

Тренутни проблеми имплементације:

Једноставна променљива account из наше претходне лекције ствара три значајна проблема која утичу и на корисничко искуство и одрживост кода:

Проблем Технички узрок Утицај на корисника
Губитак сесије Освежавање странице брише JavaScript променљиве Корисници морају често да се пријављују
Разбацана ажурирања Више функција директно мења стање Снимање грешака постаје све теже
Непотпуно чишћење Одјава не брише све референце стања Могући безбедносни и приватни ризици

Архитектонски изазов:

Као што је Титаник имао коморе које су деловале робусно све док се није напунило више комора у исто време, поправљање ових проблема појединачно неће решити основни архитектонски проблем. Потребно нам је свеобухватно решење за управљање стањем.

💡 Шта заправо покушавамо да постигнемо?

Управљање стањем је заправо решавање два основна проблема:

  1. Где су ми подаци?: Праћење шта имамо и одакле долазе подаци
  2. Да ли су сви усаглашени?: Осигурати да оно што корисници виде одговара стварном стању

Наш план игре:

Уместо да трчимо у круг, креираћемо централизовани систем управљања стањем. Замислите да имамо једну заиста организовану особу која контролише све битне ствари:

Шема која приказује ток података између HTML-а, корисничких акција и стања

flowchart TD
    A[Корисничка Акција] --> B[Обрада Догађаја]
    B --> C[фаункција updateState]
    C --> D{Валидација Стата}
    D -->|Валидан| E[Креирај Нови Стат]
    D -->|Невалидан| F[Обрада Грешке]
    E --> G[object.freeze]
    G --> H[Ажурирај localStorage]
    H --> I[Покрени Aжурирање UI]
    I --> J[Корисник Види Промене]
    F --> K[Корисник Види Грешку]
    
    subgraph "Слој Управљања Статом"
        C
        E
        G
    end
    
    subgraph "Слој Перзистенције"
        H
        L[localStorage]
        H -.-> L
    end

Разумевање овог тока података:

  • Централизује цело стање апликације на једном месту
  • Маршира све промене стања кроз контролисане функције
  • Осигурава да кориснички интерфејс остане синхронизован са тренутним стањем
  • Пружа јасан, предвидив образац за управљање подацима

💡 Професионални увид: Ова леција се фокусира на основне концепте. За сложене апликације, библиотеке као што је Redux пружају напредније могућности управљања стањем. Разумевање ових основних принципа помоћи ће вам да савладате било коју библиотеку за управљање стањем.

⚠️ Напредна тема: Нећемо покривати аутоматска ажурирања UI покренута променама стања јер то укључује концепте реактивног програмирања. Размотрите ово као одличан следећи корак у вашем учењу!

Задатак: Централизујте структуру стања

Почнимо трансформацију разбацаног управљања стањем у централизовани систем. Овај први корак поставља темеље за све будуће исправке.

Корак 1: Креирајте централни објекат стања

Замените једноставну декларацију account:

let account = null;

са структуираним објектом стања:

let state = {
  account: null
};

Зашто је ова промена важна:

  • Централизује све податке апликације на једном месту
  • Припрема структуру за додавање више својстава стања у будућности
  • Ствара јасну границу између стања и других променљивих
  • Успоставља образац који се шири како ваша апликација расте

Корак 2: Ажурирајте обрасце приступа стању

Прилагодите функције да користе нову структуру стања:

У функцијама register() и login(), замените:

account = ...

са:

state.account = ...

У функцији updateDashboard(), додајте ову линију на врх:

const account = state.account;

Шта ова ажурирања постижу:

  • Одржавају постојећу функционалност уз бољу структуру
  • Припремају ваш код за сложеније управљање стањем
  • Креирају доследне обрасце за приступ подацима стања
  • Успостављају темеље за централизована ажурирања стања

💡 Напомена: Ово рефакторисање тренутно не решава све наше проблеме, али ствара суштинске основе за моћна побољшања која следе!

🎯 Педагошки паузни тест: Принципи централизације

Пауза и Размишљање: Управо сте имплементирали темеље централизованог управљања стањем. Ово је кључна архитектонска одлука.

Брза самооцењивања:

  • Можете ли објаснити зашто је централизовање стања у једном објекту боље од разбацаних променљивих?
  • Шта би се десило ако заборавите да ажурирате функцију да користи state.account?
  • Како овај образац припрема ваш код за напредније могућности?

Веза са стварним светом: Образац централизације који сте научили је основа модерних фрејмворка као што су Redux, Vuex и React Context. Ви градите исту архитектонску концепцију коју користе велике апликације.

Изазовно питање: Ако треба да додате корисничке преференције (тему, језик) у вашу апликацију, где бисте их додали у структуру стања? Како би се ово скалирало?

Имплементација контролисаних ажурирања стања

Са централизованим стањем, следећи корак је успостављање контролисаних механизама за измене података. Овај приступ обезбеђује предвидиве промене стања и лакше снимање грешака.

Језгро овог принципа подсећа на контролу ваздушног саобраћаја: уместо да дозволимо више функција да самостално мењају стање, усмерићемо све промене кроз једну контролисану функцију. Овај образац пружа јасан надзор када и како се подаци мењају.

Управљање непромењивим стањем (Immutable):

Третираћемо наш state објекат као непромењив, што значи да га никада не мењамо директно. Уместо тога, свака промена креира нови објекат стања са ажурираним подацима.

Иако овај приступ можда у почетку изгледа неефикасно у поређењу са директним изменама, он пружа значајне предности за снимање грешака, тестирање и одрживост предвидивости апликације.

Предности управљања непромењивим стањем:

Предност Опис Утицај
Предвидивост Промене се дешавају само кроз контролисане функције Лакше снимање грешака и тестирање
Праћење историје Свако ажурирање стања креира нови објекат Омогућава функције као Undo/Redo
Превенција споредних ефеката Без случајних измена Спречава мистериозне грешке
Оптимизација перформанси Лако детектује када се стање заиста промени Омогућава ефикасна UI ажурирања

JavaScript непромењивост са Object.freeze():

JavaScript пружа Object.freeze() за спречавање измена објекта:

const immutableState = Object.freeze({ account: userData });
// Сваки покушај измене immutableState ће изазвати грешку

Објашњење шта се овде дешава:

  • Спречава директне доделе или брисање својстава
  • Баца изузетке ако се покуша измена
  • Осигурава да промене морају ићи кроз контролисане функције
  • Ствара јасан уговор о томе како се стање може мењати

💡 Детаљније: Сазнајте разлику између плитког и дубоког замрзавања објеката у MDN документацији. Разумевање ове разлике је кључно за сложене структуре стања.

stateDiagram-v2
    [*] --> StateV1: Почетно стање
    StateV1 --> StateV2: updateState('account', newData)
    StateV2 --> StateV3: updateState('account', anotherUpdate)
    StateV3 --> StateV4: updateState('preferences', userSettings)
    
    note right of StateV1
        Object.freeze()
        Неизменљиво
        Могуће дебаговање
    end note
    
    note right of StateV2
        Нови објекат је креиран
        Претходно стање сачувано
        Предвидиве промене
    end note

Задатак

Креирајмо нову функцију updateState():

function updateState(property, newData) {
  state = Object.freeze({
    ...state,
    [property]: newData
  });
}

У овој функцији креирамо нови објекат стања и копирамо податке из претходног стања коришћењем оператора ширења (...). Затим преписујемо одређено својство стања са новим подацима коришћењем нозичне нотације [property]. На крају закључавамо објекат да не би могао бити мењан коришћењем Object.freeze(). Тренутно чувајемо само својство account у стању, али овим приступом можете додати колико год својстава је потребно.

Такође ћемо ажурирати иницијализацију state како бисмо осигурали да је и почетно стање замрзнуто:

let state = Object.freeze({
  account: null
});

Након тога, ажурирајте функцију register заменом доделе state.account = result; са:

updateState('account', result);

Учинимо исто у функцији login, заменивши state.account = data; са:

updateState('account', data);

Сада ћемо искористити прилику да поправимо проблем што се подаци рачуна не бришу када корисник кликне на Logout.

Креирајте нову функцију logout():

function logout() {
  updateState('account', null);
  navigate('/login');
}

У функцији updateDashboard(), замените преусмеравање return navigate('/login'); са return logout();

Пробајте да региструјете нови рачун, одјавите се и поново пријавите да проверите да ли све исправно ради.

Савет: можете пратити све промене стања додавањем console.log(state) на дно функције updateState() и отварањем конзоле у алатима за развој у вашем прегледачу.

Имплементација перзистенције података

Проблем губитка сесије који смо раније идентификовали захтева решење перзистенције које одржава стање корисника кроз прегледачке сесије. Ово трансформише нашу апликацију из привременог искуства у поуздан, професионалан алат.

Размислите како атомски сати одржавају прецизно време чак и током прекида напајања чувајући кључне податке у непроводној меморији. Слично томе, веб апликацијама су потребни механизми за перзистентно чување који очувавају битне корисничке податке кроз сесије и освежавања страница.

Стратешка питања за перзистенцију података:

Пре имплементације перзистенције, размотрите ове критичне факторе:

Питање Контекст банкарске апликације Утицај одлуке
Да ли су подаци осетљиви? Стање рачуна, историја трансакција Одабрати безбедне методе складиштења
Колико дуго треба да се чува? Стање пријаве у поређењу са привременим корисничким подешавањима Изаберите одговарајући рок чувања
Да ли сервер треба да га има? Аутентификациони токени у поређењу са UI подешавањима Одредите захтеве за дељење

Опције за складиштење у прегледачу:

Модерни прегледачи пружају неколико механизама за чување, сваки дизајниран за различите случајеве употребе:

Примарни Storage API-ји:

  1. localStorage: Перзистентно Key/Value складиште

    • Чува податке преко сесија прегледача на неодређено време
    • Опстаје кроз поновне покрете прегледача и рачунара
    • Ограничено на специфичан домен веб сајта
    • Идеално за корисничке преференције и стање пријаве
  2. sessionStorage: Привремено сесијско складиште

    • Функционише идентично као localStorage током активних сесија
    • Брише се аутоматски када се затвори картица прегледача
    • Погодно за привремене податке који не треба да опстану
  3. HTTP Колачићи: Складиште које дели сервер

    • Аутоматски се шаљу са сваким захтевом ка серверу
    • Идеално за аутентификационе токене
    • Ограничени су по величини и могу утицати на перформансе

Потреба за серијализацијом података:

И localStorage и sessionStorage чувају само string:

// Претвори објекте у JSON низове за чување
const accountData = { user: 'john', balance: 150 };
localStorage.setItem('account', JSON.stringify(accountData));

// Парсирај JSON низове назад у објекте приликом преузимања
const savedAccount = JSON.parse(localStorage.getItem('account'));

Разумевање серијализације:

  • Претвара JavaScript објекте у JSON низове користећи JSON.stringify()
  • Реконструише објекте из JSON-а користећи JSON.parse()
  • Обрађује сложене угнежђене објекте и низове аутоматски
  • Не функционише са функцијама, undefined вредностима и кружним референцама

💡 Напредна Опција: За сложене офлајн апликације са великим скуповима података, размислите о IndexedDB API-ју. Нуди потпуну базу података на клијентској страни али захтева компликованију имплементацију.

quadrantChart
    title Опције за чување у прегледачу
    x-axis Ниска сложеност --> Висока сложеност
    y-axis Кратко трајање --> Дугачко трајање
    
    quadrant-1 Професионални алати
    quadrant-2 Једноставна упорност
    quadrant-3 Привремено чување
    quadrant-4 Напредни системи
    
    localStorage: [0.3, 0.8]
    sessionStorage: [0.2, 0.2]
    HTTP Cookies: [0.6, 0.7]
    IndexedDB: [0.9, 0.9]
    Memory Variables: [0.1, 0.1]

Задатак: Имплементирајте перзистенцију у localStorage

Хајде да имплементирамо перзистентно складиште како би корисници остали пријављени док се експлицитно не одјаве. Користићемо localStorage за чување података о налогу преко сесија прегледача.

Први корак: Defинисање конфигурације складишта

const storageKey = 'savedAccount';

Шта ова константа пружа:

  • Креира доследан идентификатор за наше податке
  • Спречава типографске грешке у референцама на кључ складишта
  • Олакшава промену кључа складишта ако је потребно
  • Прати најбоље праксе за одржив код

Други корак: Додавање аутоматске перзистенције

Додајте овај ред на крају функције updateState():

localStorage.setItem(storageKey, JSON.stringify(state.account));

Разлагање шта се овде дешава:

  • Претвара објекат налога у JSON низ за складиштење
  • Снима податке користећи наш доследни кључ за складиштење
  • Извршава се аутоматски кад год дође до промене стања
  • Обезбеђује да ће сачувани подаци увек бити синхронизовани са тренутним стањем

💡 Архитектонска предност: Јер смо централизовали све ажурирања стања преко updateState(), додавање перзистенције захтевало је само један ред кода. Ово показује снагу добрих архитектонских одлука!

Трећи корак: Враћање стања при учитавању апликације

Креирајте иницијализациону функцију за враћање сачуваних података:

function init() {
  const savedAccount = localStorage.getItem(storageKey);
  if (savedAccount) {
    updateState('account', JSON.parse(savedAccount));
  }

  // Наш претходни код за иницијализацију
  window.onpopstate = () => updateRoute();
  updateRoute();
}

init();

Разумевање процеса иницијализације:

  • Преузима било какве сачуване податке налога из localStorage
  • Парсира JSON низ назад у JavaScript објекат
  • Ажурира стање користећи нашу контролисану update функцију
  • Аутоматски враћа корисничку сесију при учитавању странице
  • Извршава се пре ажурирања рутирања како би стање било доступно

Четврти корак: Оптимизација подразумеване руте

Ажурирајте подразумевану руту да искористите предности перзистенције:

У updateRoute(), замените:

// Замени: return navigate('/login');
return navigate('/dashboard');

Зашто ова промена има смисла:

  • Искористи наш нови систем перзистенције ефикасно
  • Дозвољава контролу аутентификације преко контролне табле
  • Аутоматски преусмерава на пријаву ако нема сачуване сесије
  • Креира незнатније корисничко искуство

Тестирање ваше имплементације:

  1. Пријавите се у вашу банкарску апликацију
  2. Освежите страницу прегледача
  3. Потврдите да сте и даље пријављени и на контролној табли
  4. Затворите и поново отворите прегледач
  5. Вратите се у апликацију и потврдите да сте још увек пријављени

🎉 Остварен успех: Успешно сте имплементирали систем перзистентног управљања стањем! Ваша апликација сада ради као професионална веб апликација.

🎯 Педагошки преглед: Архитектура перзистенције

Разумевање архитектуре: Имплементирали сте софистицирани слој перзистенције који балансира корисничко искуство са сложеношћу управљања подацима.

Кључни појмови које сте савладали:

  • JSON серијализација: Претварање сложених објеката у низове за чување
  • Аутоматска синхронизација: Промене стања активирају перзистенцију
  • Оповраћај сесије: Апликације могу вратити кориснички контекст након прекида
  • Централизација перзистенције: Једна функција ажурирања управља свим складиштењем

Веза са индустријом: Овај образац перзистенције је основ за Progressive Web Apps (PWA), офлајн-прво апликације и модерна мобилна веб искуства. Градите могућности на професионалном нивоу.

Рефлексионо питање: Како бисте модификовали овај систем да подржи више корисничких налога на истом уређају? Узмите у обзир приватност и безбедност.

Балансирање перзистенције и свежине података

Наш систем перзистенције успешно одржава корисничке сесије, али уводи нови изазов: застарелост података. Када више корисника или апликација мењају исте серверске податке, локални кеширани подаци постају неажурни.

Ова ситуација подсећа на викиншке навигаторе који су рачунали и на сачуване звездне мапе и на актуелна небеска посматрања. Мапе су обезбеђивале конзистентност, али навигатори су требали свеже посматрања да би узели у обзир променљиве услове. Слично томе, нашој апликацији треба и перзистентно корисничко стање и актуелни подаци са сервера.

🧪 Откривање проблема са свежином података:

  1. Пријавите се на контролну таблу користећи налог test
  2. Пустите ову команду у терминалу да симулирате трансакцију са другог извора:
curl --request POST \
     --header "Content-Type: application/json" \
     --data "{ \"date\": \"2020-07-24\", \"object\": \"Bought book\", \"amount\": -20 }" \
     http://localhost:5000/api/accounts/test/transactions
  1. Освежите страницу контролне табле у прегледачу
  2. Пратите да ли се појављује нова трансакција

Шта овај тест демонстрира:

  • Показује како локално складиштење може постати „застарело“ (неажурно)
  • Симуилација стварних сценарија где се подаци мењају изван ваше апликације
  • Отвара тензију између перзистенције и свежине података

Изазов са застарелошћу података:

Проблем Узрок Утицај на корисника
Застарели подаци localStorage никад аутоматски не истиче Корисници виде неажурне информације
Промене на серверу Друге апликације/корисници мењају исте податке Неподударни прикази на различитим платформама
Кеширање против реалности Локални кеш не одговара стању на серверу Лоше корисничко искуство и збуњеност

Стратегија решења:

Имплементираћемо образац „освежавања при учитавању“ који балансира предности перзистенције и потребу за свежећим подацима. Овај приступ задржава глатко корисничко искуство док обезбеђује тачност података.

sequenceDiagram
    participant U as Корисник
    participant A as Апликација
    participant L as локалнаПамћење
    participant S as Сервер
    
    U->>A: Отвара апликацију
    A->>L: Учитај сачувано стање
    L-->>A: Врати кеширане податке
    A->>U: Одмах прикажи кориснички интерфејс
    A->>S: Преузми свеж податак
    S-->>A: Врати текуће податке
    A->>L: Ажурирај кеш
    A->>U: Ажурирај кориснички интерфејс са свежим подацима

Задатак: Имплементирајте систем освежавања података

Креираћемо систем који аутоматски преузима свеже податке са сервера уз одржавање предности нашег система перзистенције стања.

Први корак: Креирање ажурирача података налога

async function updateAccountData() {
  const account = state.account;
  if (!account) {
    return logout();
  }

  const data = await getAccount(account.user);
  if (data.error) {
    return logout();
  }

  updateState('account', data);
}

Логика ове функције:

  • Проверава да ли је корисник пријављен (постоји state.account)
  • Преусмерава на одјаву ако нема важећу сесију
  • Преузима свеже податке налога са сервера користећи постојећу функцију getAccount()
  • Руководи грешкама са сервера на начин да одјави неважеће сесије
  • Ажурира стање свежим подацима преко контролисаног система за ажурирање
  • Покреће аутоматску перзистенцију у localStorage кроз updateState()

Други корак: Креирање хендлера за освежавање контролне табле

async function refresh() {
  await updateAccountData();
  updateDashboard();
}

Шта ова функција за освежавање постиже:

  • Координише процес освежавања података и ажурирање UI-а
  • Чека пре него што прикаже свеже податке
  • Обезбеђује да контролна табла приказује најактуелније информације
  • Одржава јасну поделу између управљања подацима и ажурирања UI-а

Трећи корак: Интеграција са системом рутирања

Ажурирајте конфигурацију руте да аутоматски покреће освежавање:

const routes = {
  '/login': { templateId: 'login' },
  '/dashboard': { templateId: 'dashboard', init: refresh }
};

Како ова интеграција функционише:

  • Извршава функцију освежавања сваки пут када се учита рутa контролне табле
  • Обезбеђује да се увек прикажу свеже информације када корисници посете контролну таблу
  • Одржава постојећу структуру рутирања уз додатак свежине података
  • Пружа доследан образац за рутирање-специфичну иницијализацију

Тестирање вашег система освежавања података:

  1. Пријавите се у вашу банкарску апликацију
  2. Покрените curl команду из претходног корака за креирање нове трансакције
  3. Освежите страницу контролне табле или идите са ње па се вратите
  4. Потврдите да се нова трансакција одмах појављује

🎉 Постигнута савршена равнотежа: Ваша апликација сада комбинује глатко искуство перзистентног стања са тачношћу свежећих сервера података!

📈 Ваш тајмлајн за овладавање управљања стањем

timeline
    title Путовање ка професионалном управљању стањем
    
    section Препознавање проблема
        Дијагноза проблема са стањем
            : Идентификовати проблеме губитка сесије
            : Разумети проблеме са разбацаним ажурирањима
            : Препознати архитектонске потребе
    
    section Основаност архитектуре
        Централизовани дизајн стања
            : Креирати уједињене објекте стања
            : Имплементирати контролисане шаблоне ажурирања
            : Успоставити непромењиве принципе
        
        Предвидива ажурирања
            : Усавршити коришћење Object.freeze()
            : Креирати системе прилагођене дебаговању
            : Направити скалабилне шаблоне
    
    section Мастерство перзистенције
        Интеграција localStorage-а
            : Обрадити JSON серијализацију
            : Имплементирати аутоматску синхронизацију
            : Креирати континуитет сесије
        
        Баланс свежине података
            : Решити изазове застарелости
            : Креирати механизме освежавања
            : Оптимизовати перформансе у односу на прецизност
    
    section Професионални шаблони
        Системи спремни за продукцију
            : Имплементирати руковање грешкама
            : Креирати одржљиве архитектуре
            : Пратити најбоље праксе у индустрији
        
        Напредне могућности
            : Припремљени за интеграцију оквира
            : Спремни за комплексне потребе стања
            : Основа за функционалности у реалном времену

🎓 Мердјан примене: Успешно сте изградили комплетан систем управљања стањем користећи исте принципе који покрећу Redux, Vuex и друге професионалне библиотеке. Ови шаблони се скалирају од једноставних апликација до предузетничких решења.

🔄 Следећи ниво могућности:

  • Спремни сте за савладавање оквира за управљање стањем (Redux, Zustand, Pinia)
  • Припремљени да имплементирате реал-тиме функције коришћењем WebSockets
  • Опремљени за изградњу офлајн-прво Progressive Web апликација
  • Постављена основа за напредне шаблоне као што су стање машине и посматрачи

Изазов GitHub Copilot агента 🚀

Користите Agent режим за завршетак следећег изазова:

Опис: Имплементирајте свеобухватан систем управљања стањем са undo/redo функционалношћу за банкарску апликацију. Овај изазов ће вам помоћи да увежбате напредне концепте управљања стањем, укључујући праћење историје стања, иммутабилне измене и синхронизацију корисничког интерфејса.

Задатак: Креирајте проширени систем управљања стањем који укључује: 1) низ историје стања који бележи све претходне стања, 2) undo и redo функције које могу вратити претходна стања, 3) UI дугмад за undo/redo операције на контролној табли, 4) максимум од 10 стања у историји ради спречавања проблема са меморијом, и 5) правилно чишћење историје када се корисник одјави. Обезбедите да undo/redo функционише са променама стања налога и да перзистира преко освежавања прегледача.

Сазнајте више о agent режиму овде.

🚀 Изазов: Оптимизација складишта

Ваша имплементација сада ефикасно управља корисничким сесијама, освежавањем података и управљањем стањем. Међутим, размислите да ли наш тренутни приступ оптимално балансира ефикасност складиштења са функционалношћу.

Као мајстори шаха који разликују битне фигуре од резервних пешака, ефикасно управљање стањем захтева идентификовање који подаци морају да опстану, а који увек требају бити свеже преузети са сервера.

Анализа оптимизације:

Процените вашу тренутну имплементацију localStorage и размотрите ова стратешка питања:

  • Које је минимално потребно информације за одржавање аутентификације корисника?
  • Који подаци се довољно често мењају да би локално кеширање било мало корисно?
  • Како оптимизација складишта може побољшати перформансе без умањења корисничког искуства?

Ова врста архитектонске анализе разликује искусне програмере који разматрају и функционалност и ефикасност у својим решењима.

Стратегија имплементације:

  • Идентификујте суштинске податке који морају да опстану (вероватно само кориснички идентитет)
  • Модификујте вашу localStorage имплементацију да чува само критичне податке сесије
  • Обезбедите да се свеже податке увек учитавају са сервера приликом посета контролној табли
  • Тестирајте да ваш оптимизовани приступ одржава исто корисничко искуство

Напредна разматрања:

  • Упоредите компромисе између чувања потпуних података налога и само аутентификационих токена
  • Документујте ваше одлуке и образложења за будуће тимске чланове

Овај изазов ће вам помоћи да мислите као професионални програмер који разматра и корисничко искуство и ефикасност апликације. Узмите време да експериментишете са различитим приступима!

Квиз после предавања

Post-lecture quiz

Задатак

Implement "Add transaction" dialog

Ево примера резултата након завршетка задатка:

Screenshot showing an example "Add transaction" dialog


Одрицање одговорности: Овај документ је преведен помоћу AI преводилачке услуге Co-op Translator. Иако тежимо прецизности, молимо имајте у виду да аутоматизовани преводи могу садржати грешке или нетачности. Оригинални документ на његовом изворном језику треба сматрати ауторитетним извором. За критичне информације препоручује се професионални људски превод. Нисмо одговорни за било каква неспоразума или погрешне тумачења која произилазе из употребе овог превода.