31 KiB
बँकिंग अॅप तयार करा भाग 4: स्टेट मॅनेजमेंटची संकल्पना
प्री-लेक्चर क्विझ
परिचय
वेब अॅप्लिकेशन मोठे होत असताना, डेटा फ्लो ट्रॅक करणे आव्हानात्मक होते. कोणता कोड डेटा मिळवतो, कोणते पृष्ठ त्याचा वापर करते, तो कधी आणि कुठे अपडेट करायचा... हे सर्व व्यवस्थित ठेवणे कठीण होऊ शकते. विशेषतः जेव्हा तुम्हाला तुमच्या अॅपच्या वेगवेगळ्या पृष्ठांमध्ये डेटा शेअर करायचा असतो, जसे की वापरकर्त्याचा डेटा. स्टेट मॅनेजमेंट ही संकल्पना सर्व प्रकारच्या प्रोग्राम्समध्ये नेहमीच अस्तित्वात असते, परंतु वेब अॅप्स अधिक जटिल होत असल्याने विकासादरम्यान यावर विचार करणे महत्त्वाचे ठरते.
या अंतिम भागात, आपण तयार केलेल्या अॅपवर पुनर्विचार करू आणि स्टेट कसे व्यवस्थापित केले जाते ते पाहू, ब्राउझर रिफ्रेशला कोणत्याही वेळी समर्थन देणे आणि वापरकर्ता सत्रांमध्ये डेटा टिकवून ठेवणे यासाठी.
पूर्वतयारी
या धड्यासाठी तुम्ही वेब अॅपचा डेटा फेचिंग भाग पूर्ण केला असावा. तुम्हाला Node.js स्थापित करणे आणि सर्व्हर API चालवणे स्थानिक पातळीवर आवश्यक आहे जेणेकरून तुम्ही खाते डेटा व्यवस्थापित करू शकता.
सर्व्हर योग्यरित्या चालू आहे का हे तपासण्यासाठी तुम्ही टर्मिनलमध्ये हा आदेश चालवू शकता:
curl http://localhost:5000/api
# -> should return "Bank API v1.0.0" as a result
स्टेट मॅनेजमेंटवर पुनर्विचार करा
मागील धडा मध्ये, आम्ही account
नावाच्या ग्लोबल व्हेरिएबलसह अॅपमध्ये स्टेटची मूलभूत संकल्पना सादर केली होती, ज्यामध्ये सध्या लॉग इन केलेल्या वापरकर्त्याचा बँक डेटा आहे. परंतु, आमच्या सध्याच्या अंमलबजावणीमध्ये काही त्रुटी आहेत. डॅशबोर्डवर असताना पृष्ठ रिफ्रेश करण्याचा प्रयत्न करा. काय होते?
सध्याच्या कोडमध्ये 3 समस्या आहेत:
- स्टेट टिकवून ठेवले जात नाही, कारण ब्राउझर रिफ्रेश तुम्हाला लॉगिन पृष्ठावर परत नेते.
- स्टेट बदलण्यासाठी अनेक फंक्शन्स आहेत. अॅप मोठा होत असताना, बदल ट्रॅक करणे कठीण होऊ शकते आणि एखादा अपडेट विसरणे सोपे होते.
- स्टेट साफ केली जात नाही, त्यामुळे तुम्ही Logout क्लिक केल्यावरही लॉगिन पृष्ठावर असताना खाते डेटा तिथेच राहतो.
आम्ही या समस्यांवर एक-एक करून उपाय करण्यासाठी आमचा कोड अपडेट करू शकतो, परंतु यामुळे कोड डुप्लिकेशन वाढेल आणि अॅप अधिक जटिल आणि देखभाल करणे कठीण होईल. किंवा आम्ही काही मिनिटे थांबून आमची रणनीती पुन्हा विचार करू शकतो.
आम्ही येथे कोणत्या समस्या सोडवण्याचा प्रयत्न करत आहोत?
स्टेट मॅनेजमेंट म्हणजे या दोन विशिष्ट समस्यांचे चांगले समाधान शोधणे:
- अॅपमधील डेटा फ्लो समजण्यासारखा कसा ठेवायचा?
- स्टेट डेटा नेहमी वापरकर्ता इंटरफेससह (आणि उलट) समक्रमित कसा ठेवायचा?
एकदा तुम्ही याची काळजी घेतली की, तुम्हाला असलेल्या इतर कोणत्याही समस्या आधीच सोडवल्या जाऊ शकतात किंवा सोडवणे सोपे झाले आहे. या समस्यांचे निराकरण करण्यासाठी अनेक संभाव्य दृष्टिकोन आहेत, परंतु आम्ही डेटा आणि त्यात बदल करण्याचे मार्ग केंद्रीकृत करण्याचे सामान्य समाधान निवडू. डेटा फ्लो असे असेल:
आम्ही येथे डेटा स्वयंचलितपणे दृश्य अपडेट ट्रिगर करण्याचा भाग कव्हर करणार नाही, कारण ते Reactive Programming च्या अधिक प्रगत संकल्पनांशी संबंधित आहे. जर तुम्हाला सखोल अभ्यास करायचा असेल तर हा एक चांगला विषय आहे.
✅ स्टेट मॅनेजमेंटसाठी वेगवेगळ्या दृष्टिकोनांसह अनेक लायब्ररी उपलब्ध आहेत, Redux हे एक लोकप्रिय पर्याय आहे. मोठ्या वेब अॅप्समध्ये तुम्हाला कोणत्या संभाव्य समस्या येऊ शकतात आणि त्या कशा सोडवता येतील हे शिकण्यासाठी वापरले जाणारे संकल्पना आणि पॅटर्न पाहा.
कार्य
आम्ही थोडे रिफॅक्टरिंग करून सुरुवात करू. account
डिक्लरेशन बदला:
let account = null;
सह:
let state = {
account: null
};
आमच्या अॅपमधील सर्व डेटा एका सिंगल स्टेट ऑब्जेक्टमध्ये केंद्रीकृत करण्याची कल्पना आहे. सध्या स्टेटमध्ये फक्त account
आहे त्यामुळे फारसा बदल होत नाही, परंतु यामुळे भविष्यातील सुधारणा शक्य होतात.
आम्हाला ते वापरणाऱ्या फंक्शन्स देखील अपडेट कराव्या लागतील. register()
आणि login()
फंक्शन्समध्ये, account = ...
बदला state.account = ...
;
updateDashboard()
फंक्शनच्या शीर्षस्थानी, ही ओळ जोडा:
const account = state.account;
या रिफॅक्टरिंगमुळे फारसे सुधारणा झाल्या नाहीत, परंतु पुढील बदलांसाठी पाया घालणे हे उद्दिष्ट होते.
डेटा बदल ट्रॅक करा
आता आपण डेटा स्टोअर करण्यासाठी state
ऑब्जेक्ट तयार केला आहे, पुढील पायरी म्हणजे अपडेट्स केंद्रीकृत करणे. कोणतेही बदल आणि ते कधी घडतात हे ट्रॅक करणे सोपे बनवणे हे उद्दिष्ट आहे.
state
ऑब्जेक्टमध्ये बदल होऊ नयेत यासाठी, त्याला immutable मानणे चांगली पद्धत आहे, म्हणजे त्यात अजिबात बदल करता येणार नाही. याचा अर्थ तुम्हाला त्यात काहीही बदल करायचे असल्यास नवीन स्टेट ऑब्जेक्ट तयार करावा लागेल. असे करून, तुम्ही संभाव्य अवांछित side effects पासून संरक्षण तयार करता आणि तुमच्या अॅपमध्ये नवीन वैशिष्ट्ये लागू करण्यासाठी शक्यता उघडता, जसे की undo/redo लागू करणे, तसेच डिबग करणे सोपे बनवता. उदाहरणार्थ, तुम्ही स्टेटमध्ये केलेला प्रत्येक बदल लॉग करू शकता आणि बगचा स्रोत समजण्यासाठी बदलांचा इतिहास ठेवू शकता.
JavaScript मध्ये, Object.freeze()
वापरून ऑब्जेक्टची immutable आवृत्ती तयार करू शकता. जर तुम्ही immutable ऑब्जेक्टमध्ये बदल करण्याचा प्रयत्न केला तर अपवाद निर्माण होईल.
✅ shallow आणि deep immutable ऑब्जेक्टमधील फरक तुम्हाला माहित आहे का? तुम्ही याबद्दल इथे वाचू शकता.
कार्य
नवीन updateState()
फंक्शन तयार करूया:
function updateState(property, newData) {
state = Object.freeze({
...state,
[property]: newData
});
}
या फंक्शनमध्ये, आम्ही नवीन स्टेट ऑब्जेक्ट तयार करत आहोत आणि spread (...
) operator वापरून मागील स्टेटमधून डेटा कॉपी करत आहोत. नंतर आम्ही bracket notation [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();
;
नवीन खाते नोंदणी करा, लॉगआउट करा आणि पुन्हा लॉगिन करा आणि सर्व काही योग्य प्रकारे कार्य करत आहे का ते तपासा.
टिप: तुम्ही
updateState()
च्या तळाशीconsole.log(state)
जोडून आणि तुमच्या ब्राउझरच्या डेव्हलपमेंट टूल्समध्ये कन्सोल उघडून सर्व स्टेट बदल पाहू शकता.
स्टेट टिकवून ठेवा
बहुतेक वेब अॅप्सना योग्य प्रकारे कार्य करण्यासाठी डेटा टिकवून ठेवणे आवश्यक असते. सर्व महत्त्वाचा डेटा सामान्यतः डेटाबेसमध्ये संग्रहित केला जातो आणि सर्व्हर API द्वारे प्रवेश केला जातो, जसे की आमच्या बाबतीत वापरकर्ता खाते डेटा. परंतु कधीकधी, ब्राउझरमध्ये चालणाऱ्या क्लायंट अॅपवर काही डेटा टिकवून ठेवणे देखील मनोरंजक असते, चांगल्या वापरकर्ता अनुभवासाठी किंवा लोडिंग कार्यक्षमतेत सुधारणा करण्यासाठी.
जेव्हा तुम्हाला तुमच्या ब्राउझरमध्ये डेटा टिकवून ठेवायचा असतो, तेव्हा तुम्ही स्वतःला काही महत्त्वाचे प्रश्न विचारले पाहिजेत:
- डेटा संवेदनशील आहे का? तुम्ही क्लायंटवर कोणताही संवेदनशील डेटा संग्रहित करण्याचे टाळले पाहिजे, जसे की वापरकर्ता पासवर्ड.
- तुम्हाला किती काळ हा डेटा ठेवायचा आहे? तुम्ही हा डेटा फक्त चालू सत्रासाठी प्रवेश करण्याची योजना आखत आहात की तुम्हाला तो कायमस्वरूपी संग्रहित करायचा आहे?
वेब अॅपमध्ये माहिती संग्रहित करण्याचे अनेक मार्ग आहेत, तुम्हाला काय साध्य करायचे आहे यावर अवलंबून. उदाहरणार्थ, तुम्ही शोध क्वेरी संग्रहित करण्यासाठी URL वापरू शकता आणि ते वापरकर्त्यांमध्ये शेअर करण्यायोग्य बनवू शकता. तुम्ही HTTP cookies देखील वापरू शकता जर डेटा सर्व्हरसह शेअर करणे आवश्यक असेल, जसे की authentication माहिती.
डेटा संग्रहित करण्यासाठी अनेक ब्राउझर APIs आहेत. त्यापैकी दोन विशेषतः मनोरंजक आहेत:
localStorage
: एक Key/Value store जो सध्याच्या वेबसाइटसाठी विशिष्ट डेटा वेगवेगळ्या सत्रांमध्ये टिकवून ठेवतो. यात संग्रहित डेटा कधीही कालबाह्य होत नाही.sessionStorage
: हेlocalStorage
प्रमाणेच कार्य करते परंतु यात संग्रहित डेटा सत्र संपल्यावर (ब्राउझर बंद झाल्यावर) साफ केला जातो.
लक्षात घ्या की या दोन्ही APIs फक्त strings संग्रहित करण्याची परवानगी देतात. जर तुम्हाला जटिल ऑब्जेक्ट्स संग्रहित करायचे असतील, तर तुम्हाला JSON.stringify()
वापरून ते JSON स्वरूपात सिरीयलाइझ करावे लागेल.
✅ जर तुम्हाला सर्व्हरशिवाय कार्य करणारे वेब अॅप तयार करायचे असेल, तर IndexedDB
API वापरून क्लायंटवर डेटाबेस तयार करणे देखील शक्य आहे. हे प्रगत उपयोग प्रकरणांसाठी किंवा तुम्हाला मोठ्या प्रमाणात डेटा संग्रहित करायचा असल्यास राखीव आहे, कारण ते वापरण्यास अधिक जटिल आहे.
कार्य
आम्हाला आमच्या वापरकर्त्यांना Logout बटणावर स्पष्टपणे क्लिक करेपर्यंत लॉग इन ठेवायचे आहे, त्यामुळे आम्ही खाते डेटा संग्रहित करण्यासाठी localStorage
वापरू. प्रथम, आपण डेटा संग्रहित करण्यासाठी वापरण्यासाठी एक की परिभाषित करूया.
const storageKey = 'savedAccount';
मग updateState()
फंक्शनच्या शेवटी ही ओळ जोडा:
localStorage.setItem(storageKey, JSON.stringify(state.account));
यामुळे, वापरकर्ता खाते डेटा टिकवून ठेवला जाईल आणि आपण पूर्वी केंद्रीकृत केलेल्या सर्व स्टेट अपडेट्समुळे नेहमी अद्ययावत राहील. यामुळे आपल्याला पूर्वी केलेल्या सर्व रिफॅक्टरिंगचा फायदा मिळायला सुरुवात होते 🙂.
डेटा सेव्ह केला जात असल्याने, अॅप लोड झाल्यावर तो पुनर्संचयित करण्याची काळजी घेणे देखील आवश्यक आहे. आता आपल्याकडे अधिक इनिशियलायझेशन कोड असणार आहे, त्यामुळे app.js
च्या तळाशी असलेल्या पूर्वीच्या कोडसह नवीन init
फंक्शन तयार करणे चांगली कल्पना असू शकते:
function init() {
const savedAccount = localStorage.getItem(storageKey);
if (savedAccount) {
updateState('account', JSON.parse(savedAccount));
}
// Our previous initialization code
window.onpopstate = () => updateRoute();
updateRoute();
}
init();
येथे आम्ही सेव्ह केलेला डेटा पुनर्प्राप्त करतो आणि जर काही असेल तर आम्ही त्यानुसार स्टेट अपडेट करतो. हे route अपडेट करण्यापूर्वी करणे महत्त्वाचे आहे, कारण पृष्ठ अपडेट दरम्यान स्टेटवर अवलंबून असलेला कोड असू शकतो.
आम्ही Dashboard पृष्ठ आमच्या अॅप्लिकेशनचे डिफॉल्ट पृष्ठ बनवू शकतो, कारण आता आम्ही खाते डेटा टिकवून ठेवत आहोत. जर कोणताही डेटा सापडला नाही, तर डॅशबोर्ड लॉगिन पृष्ठावर रीडायरेक्ट करण्याची काळजी घेतो. updateRoute()
मध्ये, फॉलबॅक return navigate('/login');
बदला return navigate('/dashboard');
.
आता अॅपमध्ये लॉगिन करा आणि पृष्ठ रिफ्रेश करण्याचा प्रयत्न करा. तुम्ही डॅशबोर्डवरच राहाल. या अपडेटसह आपण आपल्या सर्व प्रारंभिक समस्यांचे निराकरण केले आहे...
डेटा रिफ्रेश करा
...परंतु आपण नवीन समस्या निर्माण केली असावी. ओह!
test
खाते वापरून डॅशबोर्डवर जा, नंतर टर्मिनलवर नवीन व्यवहार तयार करण्यासाठी हा आदेश चालवा:
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
आता ब्राउझरमध्ये डॅशबोर्ड पृष्ठ रिफ्रेश करण्याचा प्रयत्न करा. काय होते? तुम्हाला नवीन व्यवहार दिसतो का?
localStorage
मुळे स्टेट अनिश्चित काळासाठी टिकवून ठेवली जाते, परंतु याचा अर्थ असा आहे की तुम्ही अॅपमधून लॉगआउट करून पुन्हा लॉगिन केल्याशिवाय ती कधीही अपडेट होत नाही!
यावर उपाय करण्यासाठी एक संभाव्य रणनीती म्हणजे डॅशबोर्ड लोड झाल्यावर प्रत्येक वेळी खाते डेटा पुन्हा लोड करणे, जेणेकरून जुना डेटा टाळता येईल.
कार्य
नवीन updateAccountData
फंक्शन तयार करा:
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);
}
हे फंक्शन तपासते की आपण सध्या लॉग इन आहोत आणि नंतर सर्व्हरवरून खाते डेटा पुन्हा लोड करते.
refresh
नावाचे आणखी एक फंक्शन तयार करा:
async function refresh() {
await updateAccountData();
updateDashboard();
}
हे खाते डेटा अपडेट करते, नंतर डॅशबोर्ड पृष्ठाच्या HTML अपडेट करण्याची काळजी घेते. हे डॅशबोर्ड route लोड झाल्यावर कॉल करणे आवश्यक आहे. route डिफिनिशन अपडेट करा:
const routes = {
'/login': { templateId: 'login' },
'/dashboard': { templateId: 'dashboard', init: refresh }
};
आता डॅशबोर्ड रिफ्रेश करण्याचा प्रयत्न करा, ते अपडेट केलेला खाते डेटा प्रदर्शित करेल.
🚀 आव्हान
आता आपण डॅशबोर्ड लोड झाल्यावर प्रत्येक वेळी खाते डेटा पुन्हा लोड करतो, तुम्हाला असे वाटते का की आपल्याला संपूर्ण खाते डेटा टिकवून ठेवण्याची आवश्यकता आहे?
localStorage
मध्ये काय सेव्ह केले जाते आणि लोड केले जाते ते फक्त अॅप
ट्रान्झॅक्शन जोडण्याचा संवाद लागू करा
खालील उदाहरणात असाइनमेंट पूर्ण केल्यानंतरचा परिणाम दाखवला आहे:
अस्वीकरण:
हा दस्तऐवज AI भाषांतर सेवा Co-op Translator चा वापर करून भाषांतरित करण्यात आला आहे. आम्ही अचूकतेसाठी प्रयत्नशील असलो तरी कृपया लक्षात ठेवा की स्वयंचलित भाषांतरे त्रुटी किंवा अचूकतेच्या अभावाने युक्त असू शकतात. मूळ भाषेतील दस्तऐवज हा अधिकृत स्रोत मानला जावा. महत्त्वाच्या माहितीसाठी व्यावसायिक मानवी भाषांतराची शिफारस केली जाते. या भाषांतराचा वापर करून उद्भवलेल्या कोणत्याही गैरसमज किंवा चुकीच्या अर्थासाठी आम्ही जबाबदार राहणार नाही.