દરેક React ડેવલપરને અંતે એક જ પ્રશ્નનો સામનો કરવો પડે છે: મારે Context નો ઉપયોગ કરવો જોઈએ, કે પછી આ Redux ની સમસ્યા છે? જો તમે માત્ર થોડા મહિનાઓથી જ ડેવલપમેન્ટ કરી રહ્યા હોવ, તો ઓનલાઇન મળતી માહિતી એવી લાગે છે કે તમારે આમાંથી કોઈ એક જ પસંદ કરવું પડશે. કેટલાક ટ્યુટોરિયલ્સ Redux ને જૂની પદ્ધતિ (legacy baggage) તરીકે ગણે છે. અન્ય ચેતવણી આપે છે કે Context એક to-do લિસ્ટથી આગળ વધી શકતું નથી. આ બંનેમાંથી કોઈ પણ વિચાર ઉપયોગી નથી. સત્ય એ છે કે આ સાધનો અલગ-અલગ પ્રકારની સમસ્યાઓનું નિરાકરણ લાવે છે, અને સમજદારીપૂર્વક પસંદગી એ તમારી એપ્લિકેશન ખરેખર શું કામ કરે છે તેના પર આધાર રાખે છે.
Prop Drilling ની સમસ્યા
સ્ટેટ મેનેજમેન્ટ સ્ટ્રેટેજી પસંદ કરતા પહેલા, આ બંને સાધનો કઈ સમસ્યાનું નિરાકરણ લાવવાનો પ્રયાસ કરી રહ્યા છે તે સમજવું મદદરૂપ થશે. કલ્પના કરો કે તમે એક e-commerce સાઇટ બનાવી રહ્યા છો. તમે ટોપ-લેવલ App કમ્પોનન્ટમાં યુઝરનું પ્રોફાઇલ ફેચ કરો છો. નીચે ફૂટરમાં, એક નાનકડા AccountLink કમ્પોનન્ટને તે પ્રોફાઇલ પિક્ચરની જરૂર છે. ગ્લોબલ સ્ટોર વગર, user ઓબ્જેક્ટને Home, પછી Header, પછી NavContainer, પછી UserDropdown અને અંતે AccountLink સુધી પહોંચવું પડે છે. વચ્ચેના દરેક લેયર એ ડેટાને સ્પર્શે છે જેનો તે ઉપયોગ કરતું નથી. આને જ prop drilling કહેવાય છે.
Prop drilling કમ્પોનન્ટ્સને નબળા (brittle) બનાવે છે. Refactoring જોખમી બની જાય છે કારણ કે વચ્ચેના કોઈ એક કમ્પોનન્ટને હટાવવાથી આખી ચેઇન તૂટી જાય છે. Reusability માં પણ ઘટાડો થાય છે કારણ કે કમ્પોનન્ટ્સ એવા props માંગે છે જે તેઓ માત્ર નીચેના લેયર સુધી પહોંચાડવા માટે જ વાપરે છે. Context અને Redux બંને દૂરના કમ્પોનન્ટ્સને સીધા જ શેર કરેલા ડેટા સાથે જોડવાની (subscribe કરવાની) સુવિધા આપીને આ સમસ્યા દૂર કરે છે. પરંતુ તેઓ તે ડેટા કેવી રીતે પહોંચાડે છે અને તેની કિંમત (cost) શું છે, તે બાબતમાં બંને ઝડપથી અલગ પડે છે.
જ્યારે React Context API યોગ્ય પસંદગી હોય
React Context લાઇબ્રેરીમાં જ સામેલ છે. કોઈ વધારાના npm ઇન્સ્ટોલેશનની જરૂર નથી, કોઈ બિલ્ડ કોન્ફિગરેશન નથી, અને કોઈ બોઇલરપ્લેટ (boilerplate) ફાઇલોની જરૂર નથી. તમે એક context ઓબ્જેક્ટ બનાવો છો, તમારા ટ્રીના અમુક ભાગને Provider માં લપેટી (wrap) દો છો, અને કોઈપણ નેસ્ટેડ કમ્પોનન્ટમાં useContext દ્વારા તેની વેલ્યુનો ઉપયોગ કરો છો. આ સરળતાને કારણે, Context નાનાથી મધ્યમ કદના પ્રોજેક્ટ્સમાં શ્રેષ્ઠ કામ કરે છે જ્યાં સ્ટેટમાં ફેરફાર ભાગ્યે જ થાય છે અને સ્ટેટનું માળખું પ્રમાણમાં સરળ (flat) હોય છે.
UI થીમ્સ વિશે વિચારો. યુઝર કદાચ એક સેશનમાં એક જ વાર light અને dark મોડ વચ્ચે બદલાવ કરે છે. આ વેલ્યુ દરેક styled કમ્પોનન્ટ સુધી પહોંચે છે, પરંતુ તે એટલી ઓછી વાર બદલાય છે કે તેની પરફોર્મન્સ પર કોઈ અસર પડતી નથી. Authentication સ્ટેટસ એ બીજું એક ઉત્તમ ઉદાહરણ છે. એકવાર યુઝર લોગિન થઈ જાય પછી, isAuthenticated ફ્લેગ અને user ઓબ્જેક્ટ ડઝનબંધ પેજ નેવિગેશન્સ દરમિયાન સ્થિર રહે છે. ભાષા અથવા લોકલાઇઝેશન સેટિંગ્સ પણ આ જ રીતે કામ કરે છે. આ એવા વ્યાપક અને ધીમેથી બદલાતા સિગ્નલ્સ છે જે ઘણા કમ્પોનન્ટ્સને જોઈએ છે, પરંતુ બહુ ઓછા કમ્પોનન્ટ્સ તેને બદલે છે (mutate કરે છે).
અહીં મુખ્ય સમસ્યા એ છે કે Context અપડેટ્સને કેવી રીતે હેન્ડલ કરે છે. જ્યારે Context Provider ની વેલ્યુ બદલાય છે, ત્યારે React તે context નો ઉપયોગ કરતા દરેક કમ્પોનન્ટને ફરીથી રેન્ડર (re-render) કરે છે. નાની એપ્લિકેશનમાં તમને આનો અનુભવ થશે નહીં. પરંતુ મોટી એપ્લિકેશનમાં, જો તમે ઝડપથી બદલાતા ડેટાને વ્યાપકપણે વપરાતા Context માં રાખશો, તો તે બિનજરૂરી રેન્ડરિંગની સાંકળ (cascade of wasted renders) શરૂ કરી દેશે. તમે અસ્થિરતા (volatility) ઘટાડવા માટે અલગ-અલગ contexts બનાવી શકો છો, પરંતુ તે સમયે તમે મેન્યુઅલી એવા ઓપ્ટિમાઇઝેશન ઉપાયો કરી રહ્યા છો જે અન્ય સાધન પહેલેથી જ કરી આપે છે.
જ્યારે Redux Toolkit તેની જરૂરિયાત સાબિત કરે છે
Redux Toolkit એવી એપ્લિકેશન્સ માટે બનાવવામાં આવ્યું છે જ્યાં સ્ટેટ જટિલ હોય છે, અપડેટ્સ વારંવાર થાય છે, અને અનેક અલગ-અલગ ફીચર્સ એકબીજા સાથે અથડાયા વગર એક જ ડેટાને વાંચવા અને લખવાની જરૂર હોય છે. શૉપિંગ કાર્ટ વિશે વિચારો. યુઝર પ્રોડક્ટ કાર્ડમાંથી એક આઇટમ ઉમેરે છે. હેડરમાં રહેલા કાર્ટ આઇકને તેના બેજ કાઉન્ટને અપડેટ કરવું જોઈએ. લાઇન આઇટમ્સ બતાવવા માટે સાઇડબાર બહાર આવે છે. ડિસ્કાઉન્ટ કોડ ઇનપુટ વેલિડેશન કરે છે. ચેકઆઉટ પેજ પછી કાર્ટની વિગતો વાંચે છે. આ સ્ટેટ આખા ટ્રીમાં અલગ-અલગ કમ્પોનન્ટ્સ દ્વારા વપરાય છે અને તે વારંવાર બદલાય છે.
Redux Toolkit આ સમસ્યાનું નિરાકરણ સેન્ટ્રલાઇઝ્ડ સ્ટોર અને સ્ટેટના સ્પષ્ટ સ્લાઇસિસ (slices) દ્વારા લાવે છે. કમ્પોનન્ટ્સ useSelector નો ઉપયોગ કરીને માત્ર તેમને જરૂરી ડેટાના નાના ભાગો સાથે જ જોડાય છે. જો રિયલ-ટાઇમ ડેશબોર્ડમાં સ્ટોક પ્રાઇસ અપડેટ થાય, તો યુઝર પ્રોફાઇલ સેટિંગ્સ બતાવતા કમ્પોનન્ટને તેની જરૂર નથી પડતી. Redux અંદરખાને રેફરન્સ ઇક્વાલિટી ચેક્સ (reference equality checks) નો ઉપયોગ કરે છે જેથી સબ્સ્ક્રિપ્શન ખૂબ જ ચોકસાઈપૂર્વક (granular) હોય. જ્યારે તમારા કમ્પોનન્ટ્સની સંખ્યા સેંકડોમાં પહોંચે ત્યારે આ ખૂબ જ મહત્વપૂર્ણ બની જાય છે.
Redux તમને એક અનુમાનિત (predictable) ડેટા ફ્લો પણ આપે છે. સ્ટેટમાં ફેરફાર રેડ્યુસર્સ (reducers) દ્વારા હેન્ડલ કરવામાં આવતા ડિસ્પેચ્ડ એક્શન્સ (dispatched actions) દ્વારા થાય છે. આ સાંભળવામાં જટિલ (jargon) લાગે છે, પરંતુ વ્યવહારમાં તેનો અર્થ એ છે કે તમે તમારા કોડબેઝમાં addToCart શોધીને કાર્ટમાં ફેરફાર કરતો દરેક કોડ પાથ શોધી શકો છો. મોટી ટીમમાં, આ નિયમ બગ્સને રોકે છે. તેની સરખામણીમાં, Context માત્ર એક વેલ્યુ અને સેટર છે. કોઈપણ કન્ઝ્યુમર setState કોલ કરી શકે છે, અને ખોટી વેલ્યુનું મૂળ શોધવા માટે તમારે અનેક કમ્પોનન્ટ્સમાં બ્રેકપોઇન્ટ્સ મૂકવા પડે છે.
તેઓ ખરેખર ક્યાં અલગ પડે છે
પ્રદર્શન લાક્ષણિકતાઓ (Performance characteristics) આ સાધનોને અન્ય કોઈપણ બાબત કરતા વધુ અલગ પાડે છે. Context તમામ કન્ઝ્યુમર્સને બિનશરતી રીતે નવી વેલ્યુ બ્રોડકાસ્ટ કરે છે. Redux ફક્ત એવા સબ્સ્ક્રાઇબર્સને નોટિફાય કરે છે જેમનો પસંદ કરેલ slice બદલાયો હોય. જો તમે રિયલ-ટાઇમ સ્ટોક ડેશબોર્ડ બનાવી રહ્યા હોવ જ્યાં દર સેકન્ડે ક્વોટ્સ રિફ્રેશ થાય છે, તો Context ગ્લોબલ રી-રેન્ડર સ્ટોર્મ (global re-render storm) પેદા કરશે. Redux ફક્ત ટિકર સેલ અને સ્પાર્કલાઇન ચાર્ટને જ ફરીથી ગણતરી (recompute) કરવા દેશે.
ડીબગિંગ (Debugging) એ બીજું ક્ષેત્ર છે જ્યાં જટિલ એપ્સમાં Redux આગળ નીકળી જાય છે. Redux DevTools તમને time-travel debugging ની સુવિધા આપે છે. તમે દરેક dispatched action દ્વારા પાછળ જઈ શકો છો અને સ્ટેટ (state) ને રીવાઇન્ડ થતું જોઈ શકો છો. શિપિંગ ગણતરીઓ, પેમેન્ટ વેલિડેશન અને એરર રિકવરી સાથેના મલ્ટી-સ્ટેપ ચેકઆઉટ ફ્લોમાં, બગ તરફ દોરી જતી ચોક્કસ ક્રિયાપ્રતિક્રિયાને ફરીથી રજૂ કરી શકવું અમૂલ્ય છે. Context પ્રમાણભૂત React DevTools પર આધાર રાખે છે. તમે વર્તમાન context વેલ્યુઝનું નિરીક્ષણ કરી શકો છો, પરંતુ તેમાં કોઈ ઇન-બિલ્ટ એક્શન લોગ અથવા સ્ટેટ ડિફ વ્યુઅર નથી. તમારે ફરીથી console logs નો ઉપયોગ કરવો પડશે.
મિડલવેર અને સાઇડ ઇફેક્ટ્સ (Middleware and side effects) એ Redux ના DNA નો ભાગ છે. Redux Toolkit માં createAsyncThunk શામેલ છે અને તે ડેટા-ફેચિંગ લાઇબ્રેરીઓ સાથે સરળતાથી ઇન્ટિગ્રેટ થાય છે. તમે Redux ડેટા ફ્લોની અંદર જ API કોલનું સંચાલન કરી શકો છો, લોડિંગ સ્પિનર બતાવી શકો છો, નેટવર્ક નિષ્ફળતાને હેન્ડલ કરી શકો છો અને પરિણામને કેશ (cache) કરી શકો છો. Context અસિંક્રોનસ લોજિક (asynchronous logic) માટે કોઈ ઇન-બિલ્ટ પેટર્ન ઓફર કરતું નથી. કાં તો તમે કમ્પોનન્ટ્સની અંદર ડેટા ફેચ કરો છો અને પછી પરિણામને Context માં પુશ કરો છો, અથવા તમે હોમમેઇડ એસિંક યુટિલિટીઝમાં પ્રોવાઇડર્સને રેપ કરો છો. તે કામ કરે છે, પરંતુ તે કામચલાઉ (ad hoc) છે.
સેટઅપ ખર્ચ (Setup cost) એ એવું ક્ષેત્ર છે જ્યાં Context સ્પષ્ટ રીતે જીતે છે. થીમ પ્રોવાઇડર બનાવવા માટે લગભગ પાંચ મિનિટ લાગે છે. Redux Toolkit માટે સ્ટોર ફાઇલ બનાવવી, slices વ્યાખ્યાયિત કરવા અને તમારી એપ્લિકેશનને Provider માં રેપ કરવાની જરૂર પડે છે. તે જૂના Redux અને તેના બૉઇલરપ્લેટના પહાડો જેવી અઠવાડિયા લાંબી પ્રક્રિયા નથી, પરંતુ તે હજુ પણ Context કરતા વધુ સેટઅપ માંગે છે. વીકેન્ડ સાઇડ પ્રોજેક્ટ અથવા ત્રણ રૂટ્સ ધરાવતા ડેશબોર્ડ માટે, આ વધારાનો બોજ (overhead) લેવા જેવો ન હોઈ શકે.
એક જ એપ્લિકેશનમાં બંનેનો ઉપયોગ કરવો
તમારે કોઈ એક પક્ષ પ્રત્યે વફાદારી બતાવવાની જરૂર નથી. ઘણી પ્રોડક્શન એપ્લિકેશન્સ ગ્લોબલ UI શેલની બાબતો માટે Context અને ડોમેન-હેવી બિઝનેસ ડેટા માટે Redux નો ઉપયોગ કરે છે. એક સામાન્ય પેટર્ન એ છે કે થીમ, લોકેલ અને કદાચ એક લાઇટવેઇટ auth ફ્લેગને Context માં રાખવો કારણ કે દરેક રૂટને તેમની જરૂર હોય છે અને તેઓ ભાગ્યે જ બદલાય છે. આ દરમિયાન, ઓર્ડર મેનેજમેન્ટ સિસ્ટમ, નોટિફિકેશન સેન્ટર અને ડેટા ટેબલ્સ Redux માં રહે છે જ્યાં વારંવાર અપડેટ્સ અને ક્રોસ-કમ્પોનન્ટ લોજિક માટે ચોક્કસ નિયંત્રણની જરૂર હોય છે.
આ હાઇબ્રિડ અભિગમ સ્ટેટિક થીમ ઓબ્જેક્ટની આસપાસ સંપૂર્ણ Redux સ્ટોર લાદ્યા વિના સરળ વસ્તુઓને સરળ રાખે છે. તે તમારા Redux slices ને એવા UI chrome થી ભરાતા અટકાવે છે જેને શરૂઆતથી જ ઇન્ડસ્ટ્રીયલ-ગ્રેડ સ્ટેટ મેનેજમેન્ટની જરૂર નહોતી.
મુખ્ય નિષ્કર્ષ (The Real Takeaway)
વધારે ભારે સાધન પસંદ કરવા માટે કોઈ સન્માનનું પદ નથી. તમારું સ્ટેટ કેટલી વાર બદલાય છે, કેટલા કમ્પોનન્ટ્સ તેને સ્પર્શે છે અને શું તમારે ટીમની સીમાઓ પર મ્યુટેશનને ટ્રેસ કરવાની જરૂર છે તે જોવાથી શરૂઆત કરો. જો તમે મધ્યમ કદની એપ્લિકેશનમાં ધીમી ગતિએ બદલાતી, વ્યાપક રીતે શેર કરાયેલી વેલ્યુઝનું સંચાલન કરી રહ્યા હોવ, તો Context કદાચ પૂરતું છે. જો તમારું સ્ટેટ વારંવાર બદલાતું હોય, અસંબંધિત ફીચર્સમાં ફેલાયેલું હોય અને સ્પષ્ટ ઓડિટ ટ્રેલની જરૂર હોય, તો Redux Toolkit તમને મુશ્કેલીમાંથી બચાવશે.
તમારા પ્રોજેક્ટના સ્વરૂપના આધારે પસંદ કરો, કોન્ફરન્સની વાતો અથવા GitHub સ્ટાર્સના આધારે નહીં. પચાસ આઇટમ્સ સુધી પહોંચતી શોપિંગ કાર્ટ આપમેળે Redux ની માંગ કરતી નથી, અને થીમ ટોગલને ગ્લોબલ સ્ટોરની જરૂર નથી. સમસ્યા મુજબ સાધન પસંદ કરો, અને હાઇપ સાયકલ (hype cycle) પૂરી થયા પછી પણ તમારો કોડબેઝ મેન્ટેનેબલ રહેશે.
