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/tl/7-bank-project/4-state-management/README.md

547 lines
29 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<!--
CO_OP_TRANSLATOR_METADATA:
{
"original_hash": "32bd800759c3e943c38ad9ae6e1f51e0",
"translation_date": "2025-10-22T15:33:14+00:00",
"source_file": "7-bank-project/4-state-management/README.md",
"language_code": "tl"
}
-->
# Gumawa ng Banking App Bahagi 4: Mga Konsepto ng State Management
## Pre-Lecture Quiz
[Pre-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/47)
## Panimula
Ang state management ay parang navigation system sa Voyager spacecraft kapag maayos ang lahat, halos hindi mo mapapansin na naroroon ito. Ngunit kapag nagkaproblema, ito ang nagiging pagkakaiba sa pagitan ng pag-abot sa interstellar space at pagkaligaw sa cosmic void. Sa web development, ang state ay kumakatawan sa lahat ng kailangang tandaan ng iyong application: status ng user login, data ng form, history ng navigation, at mga pansamantalang estado ng interface.
Habang ang iyong banking app ay umunlad mula sa simpleng login form patungo sa mas sopistikadong application, malamang na nakaranas ka ng ilang karaniwang hamon. I-refresh ang pahina at biglang nalog-out ang mga user. Isara ang browser at mawawala ang lahat ng progreso. Mag-debug ng problema at maghahanap ka sa maraming function na lahat ay nagbabago ng parehong data sa iba't ibang paraan.
Hindi ito palatandaan ng masamang pag-code ito ay natural na mga hamon na nangyayari kapag ang mga application ay umabot sa isang tiyak na antas ng pagiging kumplikado. Ang bawat developer ay nakakaranas ng mga hamong ito habang ang kanilang mga app ay lumilipat mula sa "proof of concept" patungo sa "production ready."
Sa araling ito, magpapatupad tayo ng centralized state management system na magpapabago sa iyong banking app patungo sa isang maaasahan at propesyonal na application. Matututo kang pamahalaan ang daloy ng data nang predictable, panatilihin ang user sessions nang naaangkop, at lumikha ng smooth na user experience na kinakailangan ng modernong web applications.
## Mga Kinakailangan
Bago sumabak sa mga konsepto ng state management, kailangan mong maayos ang iyong development environment at ang pundasyon ng iyong banking app. Ang araling ito ay direktang nakabatay sa mga konsepto at code mula sa mga nakaraang bahagi ng seryeng ito.
Siguraduhing handa ang mga sumusunod na bahagi bago magpatuloy:
**Kinakailangang Setup:**
- Kumpletuhin ang [data fetching lesson](../3-data/README.md) - dapat matagumpay na ma-load at ma-display ng iyong app ang account data
- I-install ang [Node.js](https://nodejs.org) sa iyong sistema para sa pagtakbo ng backend API
- I-start ang [server API](../api/README.md) nang lokal para sa paghawak ng mga operasyon sa account data
**Pag-test ng Iyong Environment:**
I-verify na maayos ang pagtakbo ng iyong API server sa pamamagitan ng pag-execute ng command na ito sa terminal:
```sh
curl http://localhost:5000/api
# -> should return "Bank API v1.0.0" as a result
```
**Ano ang ginagawa ng command na ito:**
- **Nagpapadala** ng GET request sa iyong lokal na API server
- **Nagtetest** ng koneksyon at nagve-verify na tumutugon ang server
- **Nagbabalik** ng impormasyon ng API version kung maayos ang lahat
---
## Pagsusuri sa Kasalukuyang Isyu ng Estado
Tulad ni Sherlock Holmes na sinusuri ang crime scene, kailangan nating maunawaan nang eksakto kung ano ang nangyayari sa ating kasalukuyang implementasyon bago natin malutas ang misteryo ng nawawalang user sessions.
Gawin natin ang isang simpleng eksperimento na magpapakita ng mga hamon sa state management:
**🧪 Subukan ang Diagnostic Test na Ito:**
1. Mag-login sa iyong banking app at pumunta sa dashboard
2. I-refresh ang browser page
3. Obserbahan kung ano ang nangyayari sa iyong login status
Kung ikaw ay na-redirect pabalik sa login screen, natuklasan mo ang klasikong problema sa state persistence. Ang behavior na ito ay nangyayari dahil ang kasalukuyang implementasyon natin ay nag-iimbak ng user data sa JavaScript variables na nare-reset sa bawat page load.
**Mga Problema sa Kasalukuyang Implementasyon:**
Ang simpleng `account` variable mula sa ating [nakaraang aralin](../3-data/README.md) ay nagdudulot ng tatlong pangunahing isyu na nakakaapekto sa parehong user experience at code maintainability:
| Problema | Teknikal na Dahilan | Epekto sa User |
|----------|---------------------|----------------|
| **Pagkawala ng Session** | Ang page refresh ay naglilinis ng JavaScript variables | Kailangang mag-reauthenticate ng mga user nang madalas |
| **Kalituhan sa Updates** | Maraming function ang direktang nagbabago ng state | Nagiging mahirap ang pag-debug |
| **Hindi Kumpletong Cleanup** | Ang logout ay hindi naglilinis ng lahat ng state references | Posibleng mga isyu sa seguridad at privacy |
**Ang Hamon sa Arkitektura:**
Tulad ng compartmentalized design ng Titanic na tila matibay hanggang sa sabay-sabay na pagbaha ng maraming compartments, ang pag-aayos ng mga isyung ito nang paisa-isa ay hindi sasagot sa pangunahing problema sa arkitektura. Kailangan natin ng komprehensibong solusyon sa state management.
> 💡 **Ano ang talagang sinusubukan nating makamit dito?**
Ang [state management](https://en.wikipedia.org/wiki/State_management) ay tungkol sa paglutas ng dalawang pangunahing palaisipan:
1. **Nasaan ang Aking Data?**: Pagtukoy kung anong impormasyon ang mayroon tayo at saan ito nanggagaling
2. **Pareho ba ang Nakikita ng Lahat?**: Pagtitiyak na ang nakikita ng mga user ay tumutugma sa aktwal na nangyayari
**Ang Ating Plano:**
Sa halip na maghabol ng sarili nating buntot, gagawa tayo ng **centralized state management** system. Isipin ito na parang may isang maayos na tao na namamahala sa lahat ng mahalagang bagay:
![Schema na nagpapakita ng daloy ng data sa pagitan ng HTML, user actions, at state](../../../../translated_images/data-flow.fa2354e0908fecc89b488010dedf4871418a992edffa17e73441d257add18da4.tl.png)
**Pag-unawa sa daloy ng data na ito:**
- **Pinagsasama-sama** ang lahat ng application state sa isang lokasyon
- **Inaayos** ang lahat ng pagbabago sa state sa pamamagitan ng kontroladong mga function
- **Tinitiyak** na ang UI ay nananatiling naka-synchronize sa kasalukuyang state
- **Nagbibigay** ng malinaw at predictable na pattern para sa pamamahala ng data
> 💡 **Insight ng Propesyonal**: Ang araling ito ay nakatuon sa mga pangunahing konsepto. Para sa mas kumplikadong mga application, ang mga library tulad ng [Redux](https://redux.js.org) ay nagbibigay ng mas advanced na mga feature sa state management. Ang pag-unawa sa mga pangunahing prinsipyo na ito ay makakatulong sa iyong ma-master ang anumang state management library.
> ⚠️ **Advanced na Paksa**: Hindi natin tatalakayin ang automatic UI updates na triggered ng state changes, dahil ito ay may kinalaman sa mga konsepto ng [Reactive Programming](https://en.wikipedia.org/wiki/Reactive_programming). Isipin ito bilang isang mahusay na susunod na hakbang para sa iyong pag-aaral!
### Gawain: I-centralize ang State Structure
Simulan natin ang pag-transform ng ating scattered state management patungo sa isang centralized system. Ang unang hakbang na ito ay nagtatatag ng pundasyon para sa lahat ng mga susunod na pagpapabuti.
**Hakbang 1: Gumawa ng Central State Object**
Palitan ang simpleng deklarasyon ng `account`:
```js
let account = null;
```
Gamit ang structured state object:
```js
let state = {
account: null
};
```
**Bakit mahalaga ang pagbabagong ito:**
- **Pinagsasama-sama** ang lahat ng application data sa isang lokasyon
- **Inihahanda** ang istruktura para sa pagdaragdag ng mas maraming state properties sa hinaharap
- **Lumilikha** ng malinaw na hangganan sa pagitan ng state at iba pang mga variable
- **Nagtatatag** ng pattern na maaaring mag-scale habang lumalaki ang iyong app
**Hakbang 2: I-update ang State Access Patterns**
I-update ang iyong mga function upang gamitin ang bagong state structure:
**Sa mga `register()` at `login()` function**, palitan:
```js
account = ...
```
Gamit:
```js
state.account = ...
```
**Sa `updateDashboard()` function**, idagdag ang linyang ito sa itaas:
```js
const account = state.account;
```
**Ano ang nagagawa ng mga update na ito:**
- **Pinapanatili** ang kasalukuyang functionality habang pinapabuti ang istruktura
- **Inihahanda** ang iyong code para sa mas sopistikadong state management
- **Lumilikha** ng consistent na pattern para sa pag-access ng state data
- **Nagtatatag** ng pundasyon para sa centralized state updates
> 💡 **Tandaan**: Ang refactoring na ito ay hindi agad-agad na malulutas ang ating mga problema, ngunit nililikha nito ang mahalagang pundasyon para sa mga makapangyarihang pagpapabuti na darating!
## Pagpapatupad ng Controlled State Updates
Kapag centralized na ang ating state, ang susunod na hakbang ay ang pagtatatag ng kontroladong mekanismo para sa mga pagbabago sa data. Ang approach na ito ay tinitiyak ang predictable na state changes at mas madaling pag-debug.
Ang pangunahing prinsipyo ay parang air traffic control: sa halip na payagan ang maraming function na magbago ng state nang independiyente, idadaan natin ang lahat ng pagbabago sa isang solong, kontroladong function. Ang pattern na ito ay nagbibigay ng malinaw na oversight kung kailan at paano nagbabago ang data.
**Immutable State Management:**
Ituturing natin ang ating `state` object bilang [*immutable*](https://en.wikipedia.org/wiki/Immutable_object), ibig sabihin hindi natin ito direktang babaguhin. Sa halip, bawat pagbabago ay lumilikha ng bagong state object na may updated na data.
Bagamat ang approach na ito ay maaaring mukhang hindi efficient kumpara sa direktang pagbabago, nagbibigay ito ng malaking benepisyo para sa debugging, testing, at pagpapanatili ng predictability ng application.
**Mga Benepisyo ng Immutable State Management:**
| Benepisyo | Deskripsyon | Epekto |
|----------|-------------|--------|
| **Predictability** | Ang mga pagbabago ay nangyayari lamang sa pamamagitan ng kontroladong mga function | Mas madaling i-debug at i-test |
| **History Tracking** | Ang bawat pagbabago sa state ay lumilikha ng bagong object | Nagbibigay-daan sa undo/redo functionality |
| **Side Effect Prevention** | Walang aksidenteng pagbabago | Pinipigilan ang misteryosong mga bug |
| **Performance Optimization** | Madaling matukoy kung kailan nagbago ang state | Nagbibigay-daan sa efficient na UI updates |
**JavaScript Immutability gamit ang `Object.freeze()`:**
Nagbibigay ang JavaScript ng [`Object.freeze()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze) upang pigilan ang mga pagbabago sa object:
```js
const immutableState = Object.freeze({ account: userData });
// Any attempt to modify immutableState will throw an error
```
**Pag-unawa sa nangyayari dito:**
- **Pinipigilan** ang direktang pag-assign o pag-delete ng properties
- **Nagbibigay** ng exceptions kung may pagtatangkang baguhin ang object
- **Tinitiyak** na ang mga pagbabago sa state ay dapat dumaan sa kontroladong mga function
- **Lumilikha** ng malinaw na kontrata kung paano maaaring ma-update ang state
> 💡 **Malalim na Pagsisiyasat**: Alamin ang pagkakaiba sa pagitan ng *shallow* at *deep* immutable objects sa [MDN documentation](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze#What_is_shallow_freeze). Mahalagang maunawaan ang pagkakaibang ito para sa mga kumplikadong state structures.
### Gawain
Gumawa tayo ng bagong `updateState()` function:
```js
function updateState(property, newData) {
state = Object.freeze({
...state,
[property]: newData
});
}
```
Sa function na ito, gumagawa tayo ng bagong state object at kinokopya ang data mula sa nakaraang state gamit ang [*spread (`...`) operator*](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/Spread_syntax#Spread_in_object_literals). Pagkatapos, pinapalitan natin ang partikular na property ng state object gamit ang [bracket notation](https://developer.mozilla.org/docs/Web/JavaScript/Guide/Working_with_Objects#Objects_and_properties) `[property]` para sa assignment. Sa huli, nilalock natin ang object upang pigilan ang mga pagbabago gamit ang `Object.freeze()`. Sa ngayon, mayroon lamang tayong `account` property na naka-store sa state, ngunit sa approach na ito maaari kang magdagdag ng mas maraming properties sa state.
I-update din natin ang `state` initialization upang matiyak na ang initial state ay frozen din:
```js
let state = Object.freeze({
account: null
});
```
Pagkatapos nito, i-update ang `register` function sa pamamagitan ng pagpapalit ng `state.account = result;` assignment sa:
```js
updateState('account', result);
```
Gawin din ito sa `login` function, palitan ang `state.account = data;` ng:
```js
updateState('account', data);
```
Ngayon, samantalahin natin ang pagkakataon upang ayusin ang isyu ng hindi pag-clear ng account data kapag nag-click ang user sa *Logout*.
Gumawa ng bagong function na `logout()`:
```js
function logout() {
updateState('account', null);
navigate('/login');
}
```
Sa `updateDashboard()`, palitan ang redirection na `return navigate('/login');` ng `return logout()`;
Subukang mag-register ng bagong account, mag-logout, at mag-login muli upang suriin kung maayos pa rin ang lahat.
> Tip: maaari mong tingnan ang lahat ng pagbabago sa state sa pamamagitan ng pagdaragdag ng `console.log(state)` sa ibaba ng `updateState()` at pagbukas ng console sa development tools ng iyong browser.
## Pagpapatupad ng Data Persistence
Ang isyu ng session loss na natukoy natin kanina ay nangangailangan ng persistence solution na nagpapanatili ng user state sa mga session ng browser. Binabago nito ang ating application mula sa isang pansamantalang karanasan patungo sa isang maaasahan at propesyonal na tool.
Isipin kung paano pinapanatili ng atomic clocks ang eksaktong oras kahit na may power outages sa pamamagitan ng pag-iimbak ng critical state sa non-volatile memory. Katulad nito, ang mga web application ay nangangailangan ng persistent storage mechanisms upang mapanatili ang mahalagang user data sa mga session ng browser at page refreshes.
**Mga Strategic na Tanong para sa Data Persistence:**
Bago magpatupad ng persistence, isaalang-alang ang mga kritikal na salik na ito:
| Tanong | Konteksto ng Banking App | Epekto ng Desisyon |
|-------|--------------------------|-------------------|
| **Sensitive ba ang data?** | Account balance, transaction history | Pumili ng secure na storage methods |
| **Gaano katagal dapat mag-persist?** | Login state vs. temporary UI preferences | Pumili ng naaangkop na storage duration |
| **Kailangan ba ito ng server?** | Authentication tokens vs. UI settings | Tukuyin ang mga sharing requirements |
**Mga Opsyon sa Browser Storage:**
Nagbibigay ang modernong browsers ng ilang storage mechanisms, bawat isa ay idinisenyo para sa iba't ibang use cases:
**Pangunahing Storage APIs:**
1. **[`localStorage`](https://developer.mozilla.org/docs/Web/API/Window/localStorage)**: Persistent [Key/Value storage](https://en.wikipedia.org/wiki/Key%E2%80%93value_database)
- **Nagpapanatili** ng data sa mga session ng browser nang walang hanggan
- **Nananatili** kahit i-restart ang browser at computer
- **Nakatuon** sa partikular na domain ng website
- **Perpekto** para sa user preferences at login states
2. **[`sessionStorage`](https://developer.mozilla.org/docs/Web/API/Window/sessionStorage)**: Temporary session storage
- **Gumagana** nang katulad sa localStorage sa mga aktibong session
- **Awtomatikong nawawala** kapag isinara ang browser tab
- **Mainam** para sa pansamantalang data na hindi dapat mag-persist
3. **[HTTP Cookies](https://developer.mozilla.org/docs/Web/HTTP/Cookies)**: Server-shared storage
- **Awtomatikong** ipinapadala sa bawat server request
- **Perpekto** para sa [authentication](https://en.wikipedia.org/wiki/Authentication) tokens
- **Limitado** ang laki at maaaring makaapekto sa performance
**Kinakailangan ang Data Serialization:**
Ang parehong `localStorage` at `sessionStorage` ay nag-iimbak lamang ng [strings](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String):
```js
// Convert objects to JSON strings for storage
const accountData = { user: 'john', balance: 150 };
localStorage.setItem('account', JSON.stringify(accountData));
// Parse JSON strings back to objects when retrieving
const savedAccount = JSON.parse(localStorage.getItem('account'));
```
**Pag-unawa sa serialization:**
- **Nagko-convert** ng JavaScript objects sa JSON strings gamit ang [`JSON.stringify()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify)
- **Binubuo muli** ang objects mula sa JSON gamit ang [`JSON.parse()`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse)
- **Awtomatikong hinahandle** ang mga kumplikadong nested objects at arrays
- **Hindi gumagana** sa functions, undefined values, at circular references
> 💡 **Advanced Option**: Para sa mga kumplikadong offline na aplikasyon na may malalaking dataset, isaalang-alang ang [`IndexedDB` API](https://developer.mozilla.org/docs/Web/API/IndexedDB_API). Nagbibigay ito ng buong client-side database ngunit nangangailangan ng mas kumplikadong implementasyon.
### Gawain: Ipatupad ang localStorage Persistence
Ipatupad natin ang persistent storage upang manatiling naka-log in ang mga user hanggang sa sila mismo ang mag-log out. Gagamit tayo ng `localStorage` para i-store ang account data sa iba't ibang browser session.
**Hakbang 1: Tukuyin ang Storage Configuration**
```js
const storageKey = 'savedAccount';
```
**Ano ang ibinibigay ng constant na ito:**
- **Lumilikha** ng consistent identifier para sa ating stored data
- **Pinipigilan** ang mga typo sa storage key references
- **Ginagawang** madali ang pagbabago ng storage key kung kinakailangan
- **Sumusunod** sa best practices para sa maintainable na code
**Hakbang 2: Magdagdag ng Automatic Persistence**
Idagdag ang linyang ito sa dulo ng `updateState()` function:
```js
localStorage.setItem(storageKey, JSON.stringify(state.account));
```
**Pag-unawa sa nangyayari dito:**
- **Kinoconvert** ang account object sa JSON string para sa storage
- **Sinasave** ang data gamit ang ating consistent storage key
- **Ina-execute** ito nang awtomatiko tuwing may pagbabago sa state
- **Tinitiyak** na ang stored data ay palaging synchronized sa kasalukuyang state
> 💡 **Benepisyo ng Arkitektura**: Dahil na-centralize natin ang lahat ng state updates sa pamamagitan ng `updateState()`, ang pagdaragdag ng persistence ay nangangailangan lamang ng isang linya ng code. Ipinapakita nito ang kapangyarihan ng mahusay na desisyon sa arkitektura!
**Hakbang 3: Ibalik ang State sa Pag-load ng App**
Gumawa ng initialization function para maibalik ang na-save na data:
```js
function init() {
const savedAccount = localStorage.getItem(storageKey);
if (savedAccount) {
updateState('account', JSON.parse(savedAccount));
}
// Our previous initialization code
window.onpopstate = () => updateRoute();
updateRoute();
}
init();
```
**Pag-unawa sa proseso ng initialization:**
- **Kinukuha** ang anumang na-save na account data mula sa localStorage
- **Pinoproseso** ang JSON string pabalik sa JavaScript object
- **Ina-update** ang state gamit ang ating controlled update function
- **Ibinabalik** ang session ng user nang awtomatiko sa pag-load ng page
- **Ina-execute** ito bago ang mga update sa ruta upang matiyak na available ang state
**Hakbang 4: I-optimize ang Default Route**
I-update ang default route upang magamit ang persistence:
Sa `updateRoute()`, palitan:
```js
// Replace: return navigate('/login');
return navigate('/dashboard');
```
**Bakit makatuwiran ang pagbabagong ito:**
- **Ginagamit** nang epektibo ang bagong persistence system
- **Pinapayagan** ang dashboard na mag-handle ng authentication checks
- **Nagre-redirect** sa login nang awtomatiko kung walang na-save na session
- **Lumilikha** ng mas seamless na karanasan para sa user
**Pagsubok sa Iyong Implementasyon:**
1. Mag-log in sa iyong banking app
2. I-refresh ang browser page
3. Tiyaking nananatili kang naka-log in at nasa dashboard
4. Isara at muling buksan ang iyong browser
5. Bumalik sa iyong app at kumpirmahing naka-log in ka pa rin
🎉 **Achievement Unlocked**: Matagumpay mong naipatupad ang persistent state management! Ang iyong app ay kumikilos na tulad ng isang propesyonal na web application.
## Pagbalanse ng Persistence at Data Freshness
Ang ating persistence system ay matagumpay na nagpapanatili ng user sessions, ngunit nagdadala ng bagong hamon: data staleness. Kapag maraming user o aplikasyon ang nagbabago ng parehong server data, ang lokal na naka-cache na impormasyon ay nagiging luma.
Ang sitwasyong ito ay kahalintulad ng mga Viking navigator na umaasa sa parehong naka-store na star charts at kasalukuyang celestial observations. Ang charts ay nagbibigay ng consistency, ngunit kailangan ng mga navigator ng sariwang obserbasyon upang ma-account ang mga nagbabagong kondisyon. Katulad nito, ang ating aplikasyon ay nangangailangan ng parehong persistent user state at kasalukuyang server data.
**🧪 Pagdiskubre sa Problema ng Data Freshness:**
1. Mag-log in sa dashboard gamit ang `test` account
2. Patakbuhin ang command na ito sa terminal upang mag-simulate ng transaction mula sa ibang source:
```sh
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
```
3. I-refresh ang iyong dashboard page sa browser
4. Obserbahan kung makikita mo ang bagong transaction
**Ano ang ipinapakita ng test na ito:**
- **Ipinapakita** kung paano nagiging "stale" (luma) ang local storage
- **Sinasalamin** ang mga real-world scenario kung saan nagbabago ang data sa labas ng iyong app
- **Ibinubunyag** ang tensyon sa pagitan ng persistence at data freshness
**Ang Hamon ng Data Staleness:**
| Problema | Sanhi | Epekto sa User |
|----------|-------|----------------|
| **Stale Data** | Ang localStorage ay hindi awtomatikong nag-e-expire | Nakikita ng user ang lumang impormasyon |
| **Server Changes** | Binabago ng ibang apps/users ang parehong data | Hindi consistent ang view sa iba't ibang platform |
| **Cache vs. Reality** | Ang lokal na cache ay hindi tumutugma sa server state | Mahinang karanasan ng user at kalituhan |
**Solusyon na Estratehiya:**
Magpapatupad tayo ng "refresh on load" pattern na nagbabalanse sa benepisyo ng persistence at pangangailangan para sa sariwang data. Ang approach na ito ay nagpapanatili ng maayos na karanasan ng user habang tinitiyak ang katumpakan ng data.
### Gawain: Ipatupad ang Data Refresh System
Gagawa tayo ng sistema na awtomatikong kumukuha ng sariwang data mula sa server habang pinapanatili ang benepisyo ng ating persistent state management.
**Hakbang 1: Gumawa ng Account Data Updater**
```js
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);
}
```
**Pag-unawa sa lohika ng function na ito:**
- **Sinusuri** kung ang user ay kasalukuyang naka-log in (may state.account)
- **Nagre-redirect** sa logout kung walang valid session
- **Kumukuha** ng sariwang account data mula sa server gamit ang umiiral na `getAccount()` function
- **Ina-handle** ang server errors nang maayos sa pamamagitan ng pag-log out ng invalid sessions
- **Ina-update** ang state gamit ang sariwang data sa pamamagitan ng ating controlled update system
- **Nagti-trigger** ng awtomatikong localStorage persistence sa pamamagitan ng `updateState()` function
**Hakbang 2: Gumawa ng Dashboard Refresh Handler**
```js
async function refresh() {
await updateAccountData();
updateDashboard();
}
```
**Ano ang nagagawa ng refresh function na ito:**
- **Kinokoordina** ang proseso ng data refresh at UI update
- **Naghihintay** para ma-load ang sariwang data bago i-update ang display
- **Tinitiyak** na ang dashboard ay nagpapakita ng pinakabagong impormasyon
- **Pinapanatili** ang malinis na paghihiwalay sa pagitan ng data management at UI updates
**Hakbang 3: Isama sa Route System**
I-update ang iyong route configuration upang awtomatikong mag-trigger ng refresh:
```js
const routes = {
'/login': { templateId: 'login' },
'/dashboard': { templateId: 'dashboard', init: refresh }
};
```
**Paano gumagana ang integration na ito:**
- **Ina-execute** ang refresh function tuwing naglo-load ang dashboard route
- **Tinitiyak** na sariwang data ang palaging ipinapakita kapag nag-navigate ang user sa dashboard
- **Pinapanatili** ang umiiral na route structure habang nagdadagdag ng data freshness
- **Nagbibigay** ng consistent na pattern para sa route-specific initialization
**Pagsubok sa Iyong Data Refresh System:**
1. Mag-log in sa iyong banking app
2. Patakbuhin ang curl command mula kanina upang gumawa ng bagong transaction
3. I-refresh ang iyong dashboard page o mag-navigate palayo at bumalik
4. Tiyaking lumalabas agad ang bagong transaction
🎉 **Perfect Balance Achieved**: Ang iyong app ay ngayon pinagsasama ang maayos na karanasan ng persistent state at ang katumpakan ng sariwang server data!
## Hamon ng GitHub Copilot Agent 🚀
Gamitin ang Agent mode upang kumpletuhin ang sumusunod na hamon:
**Deskripsyon:** Ipatupad ang isang komprehensibong state management system na may undo/redo functionality para sa banking app. Ang hamon na ito ay makakatulong sa iyo na magsanay sa advanced state management concepts kabilang ang state history tracking, immutable updates, at user interface synchronization.
**Prompt:** Gumawa ng enhanced state management system na kinabibilangan ng: 1) Isang state history array na nagta-track ng lahat ng nakaraang states, 2) Undo at redo functions na maaaring bumalik sa mga nakaraang states, 3) UI buttons para sa undo/redo operations sa dashboard, 4) Maximum history limit na 10 states upang maiwasan ang memory issues, at 5) Tamang cleanup ng history kapag nag-log out ang user. Tiyaking gumagana ang undo/redo functionality sa mga pagbabago sa account balance at nananatili ito sa browser refreshes.
Alamin pa ang tungkol sa [agent mode](https://code.visualstudio.com/blogs/2025/02/24/introducing-copilot-agent-mode) dito.
## 🚀 Hamon: Storage Optimization
Ang iyong implementasyon ay ngayon humahawak sa user sessions, data refresh, at state management nang epektibo. Gayunpaman, isaalang-alang kung ang kasalukuyang approach ay optimal sa pagbalanse ng storage efficiency at functionality.
Tulad ng mga chess masters na nakikilala ang mahalagang piraso mula sa mga expendable pawns, ang epektibong state management ay nangangailangan ng pagtukoy kung aling data ang kailangang mag-persist kumpara sa kung alin ang dapat palaging sariwa mula sa server.
**Optimization Analysis:**
Suriin ang iyong kasalukuyang localStorage implementation at isaalang-alang ang mga estratehikong tanong na ito:
- Ano ang minimum na impormasyon na kinakailangan upang mapanatili ang user authentication?
- Aling data ang madalas magbago kaya't ang lokal na caching ay nagbibigay ng kaunting benepisyo?
- Paano makakatulong ang storage optimization sa pagpapabuti ng performance nang hindi nakokompromiso ang karanasan ng user?
**Implementation Strategy:**
- **Tukuyin** ang mahalagang data na kailangang mag-persist (malamang user identification lang)
- **Baguhin** ang iyong localStorage implementation upang mag-store lamang ng critical session data
- **Tiyakin** na ang sariwang data ay palaging na-load mula sa server sa mga pagbisita sa dashboard
- **Subukan** kung ang iyong optimized approach ay nagpapanatili ng parehong karanasan ng user
**Advanced Consideration:**
- **Ihambing** ang trade-offs sa pagitan ng pag-store ng buong account data vs. authentication tokens lamang
- **I-dokumenta** ang iyong mga desisyon at pangangatwiran para sa mga susunod na miyembro ng team
Ang hamon na ito ay makakatulong sa iyo na mag-isip tulad ng isang propesyonal na developer na isinasaalang-alang ang parehong karanasan ng user at kahusayan ng aplikasyon. Maglaan ng oras upang mag-eksperimento sa iba't ibang approach!
## Post-Lecture Quiz
[Post-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/48)
## Takdang-Aralin
[Implement "Add transaction" dialog](assignment.md)
Narito ang isang halimbawa ng resulta pagkatapos makumpleto ang takdang-aralin:
![Screenshot na nagpapakita ng halimbawa ng "Add transaction" dialog](../../../../translated_images/dialog.93bba104afeb79f12f65ebf8f521c5d64e179c40b791c49c242cf15f7e7fab15.tl.png)
---
**Paunawa**:
Ang dokumentong ito ay isinalin gamit ang AI translation service na [Co-op Translator](https://github.com/Azure/co-op-translator). Bagamat sinisikap naming maging tumpak, pakatandaan na ang mga awtomatikong pagsasalin ay maaaring maglaman ng mga pagkakamali o hindi pagkakatugma. Ang orihinal na dokumento sa kanyang katutubong wika ang dapat ituring na opisyal na sanggunian. Para sa mahalagang impormasyon, inirerekomenda ang propesyonal na pagsasalin ng tao. Hindi kami mananagot sa anumang hindi pagkakaunawaan o maling interpretasyon na dulot ng paggamit ng pagsasaling ito.