જટિલ એપ્લિકેશન સ્ટેટ્સને અસરકારક રીતે મેનેજ કરવા માટે React ના useReducer હૂકમાં ઊંડા ઉતરો, જે વૈશ્વિક React પ્રોજેક્ટ્સ માટે પ્રદર્શન અને જાળવણીને વધારે છે.
React useReducer પેટર્ન: જટિલ સ્ટેટ મેનેજમેન્ટમાં નિપુણતા
ફ્રન્ટ-એન્ડ ડેવલપમેન્ટના સતત વિકસતા ક્ષેત્રમાં, React એ યુઝર ઇન્ટરફેસ બનાવવા માટે એક અગ્રણી ફ્રેમવર્ક તરીકે પોતાને સ્થાપિત કર્યું છે. જેમ જેમ એપ્લિકેશન્સની જટિલતા વધતી જાય છે, તેમ સ્ટેટનું સંચાલન કરવું વધુને વધુ પડકારજનક બને છે. useState
હૂક એક કોમ્પોનન્ટની અંદર સ્ટેટનું સંચાલન કરવાની એક સરળ રીત પ્રદાન કરે છે, પરંતુ વધુ જટિલ પરિસ્થિતિઓ માટે, React એક શક્તિશાળી વિકલ્પ પ્રદાન કરે છે: useReducer
હૂક. આ બ્લોગ પોસ્ટ useReducer
પેટર્નમાં ઊંડાણપૂર્વક ઉતરે છે, તેના ફાયદાઓ, વ્યવહારુ અમલીકરણો અને તે કેવી રીતે વૈશ્વિક સ્તરે તમારી React એપ્લિકેશન્સને નોંધપાત્ર રીતે સુધારી શકે છે તેનું અન્વેષણ કરે છે.
જટિલ સ્ટેટ મેનેજમેન્ટની જરૂરિયાતને સમજવું
React એપ્લિકેશન્સ બનાવતી વખતે, આપણે ઘણીવાર એવી પરિસ્થિતિઓનો સામનો કરીએ છીએ જ્યાં કોમ્પોનન્ટની સ્થિતિ માત્ર એક સરળ મૂલ્ય નથી, પરંતુ એકબીજા સાથે જોડાયેલા ડેટા પોઈન્ટ્સનો સંગ્રહ અથવા એવી સ્થિતિ છે જે અગાઉના સ્ટેટ મૂલ્યો પર આધાર રાખે છે. આ ઉદાહરણોનો વિચાર કરો:
- વપરાશકર્તા પ્રમાણીકરણ: લૉગિન સ્થિતિ, વપરાશકર્તાની વિગતો અને પ્રમાણીકરણ ટોકન્સનું સંચાલન કરવું.
- ફોર્મ હેન્ડલિંગ: બહુવિધ ઇનપુટ ફીલ્ડ્સના મૂલ્યો, માન્યતા ભૂલો અને સબમિશન સ્થિતિને ટ્રેક કરવું.
- ઈ-કોમર્સ કાર્ટ: વસ્તુઓ, જથ્થો, કિંમતો અને ચેકઆઉટ માહિતીનું સંચાલન કરવું.
- રીઅલ-ટાઇમ ચેટ એપ્લિકેશન્સ: સંદેશાઓ, વપરાશકર્તાની હાજરી અને કનેક્શન સ્થિતિનું સંચાલન કરવું.
આ પરિસ્થિતિઓમાં, ફક્ત useState
નો ઉપયોગ કરવાથી જટિલ અને સંચાલન કરવામાં મુશ્કેલ કોડ થઈ શકે છે. એક જ ઘટનાના પ્રતિભાવમાં બહુવિધ સ્ટેટ વેરિયેબલ્સને અપડેટ કરવું બોજારૂપ બની શકે છે, અને આ અપડેટ્સનું સંચાલન કરવા માટેનું તર્ક સમગ્ર કોમ્પોનન્ટમાં વિખરાયેલું બની શકે છે, જે તેને સમજવા અને જાળવવામાં મુશ્કેલ બનાવે છે. અહીં જ useReducer
ચમકે છે.
useReducer
હૂકનો પરિચય
useReducer
હૂક એ જટિલ સ્ટેટ લોજિકના સંચાલન માટે useState
નો વિકલ્પ છે. તે Redux પેટર્નના સિદ્ધાંતો પર આધારિત છે, પરંતુ તે React કોમ્પોનન્ટની અંદર જ લાગુ કરવામાં આવે છે, જે ઘણા કિસ્સાઓમાં અલગ બાહ્ય લાઇબ્રેરીની જરૂરિયાતને દૂર કરે છે. તે તમને તમારા સ્ટેટ અપડેટ લોજિકને એક જ ફંક્શનમાં કેન્દ્રિત કરવાની મંજૂરી આપે છે જેને રિડ્યુસર કહેવાય છે.
useReducer
હૂક બે દલીલો લે છે:
- એક રિડ્યુસર ફંક્શન: આ એક શુદ્ધ ફંક્શન છે જે વર્તમાન સ્ટેટ અને એક્શનને ઇનપુટ તરીકે લે છે અને નવું સ્ટેટ પરત કરે છે.
- એક પ્રારંભિક સ્ટેટ: આ સ્ટેટનું પ્રારંભિક મૂલ્ય છે.
હૂક બે ઘટકો ધરાવતો એરે પરત કરે છે:
- વર્તમાન સ્ટેટ: આ સ્ટેટનું વર્તમાન મૂલ્ય છે.
- એક ડિસ્પેચ ફંક્શન: આ ફંક્શનનો ઉપયોગ રિડ્યુસરને એક્શન્સ ડિસ્પેચ કરીને સ્ટેટ અપડેટ્સને ટ્રિગર કરવા માટે થાય છે.
રિડ્યુસર ફંક્શન
રિડ્યુસર ફંક્શન એ useReducer
પેટર્નનું હૃદય છે. તે એક શુદ્ધ ફંક્શન છે, જેનો અર્થ છે કે તેની કોઈ આડઅસર ન હોવી જોઈએ (જેમ કે API કૉલ્સ કરવા અથવા વૈશ્વિક વેરિયેબલ્સમાં ફેરફાર કરવો) અને હંમેશા સમાન ઇનપુટ માટે સમાન આઉટપુટ પરત કરવું જોઈએ. રિડ્યુસર ફંક્શન બે દલીલો લે છે:
state
: વર્તમાન સ્ટેટ.action
: એક ઑબ્જેક્ટ જે વર્ણવે છે કે સ્ટેટ સાથે શું થવું જોઈએ. એક્શન્સમાં સામાન્ય રીતેtype
પ્રોપર્ટી હોય છે જે એક્શનનો પ્રકાર સૂચવે છે અનેpayload
પ્રોપર્ટી હોય છે જેમાં એક્શન સંબંધિત ડેટા હોય છે.
રિડ્યુસર ફંક્શનની અંદર, તમે વિવિધ એક્શન પ્રકારોને હેન્ડલ કરવા અને તે મુજબ સ્ટેટને અપડેટ કરવા માટે switch
સ્ટેટમેન્ટ અથવા if/else if
સ્ટેટમેન્ટનો ઉપયોગ કરો છો. આ તમારા સ્ટેટ અપડેટ લોજિકને કેન્દ્રિત કરે છે અને વિવિધ ઘટનાઓના પ્રતિભાવમાં સ્ટેટ કેવી રીતે બદલાય છે તે વિશે તર્ક કરવાનું સરળ બનાવે છે.
ડિસ્પેચ ફંક્શન
ડિસ્પેચ ફંક્શન એ પદ્ધતિ છે જેનો ઉપયોગ તમે સ્ટેટ અપડેટ્સને ટ્રિગર કરવા માટે કરો છો. જ્યારે તમે dispatch(action)
ને કૉલ કરો છો, ત્યારે એક્શનને રિડ્યુસર ફંક્શનમાં પસાર કરવામાં આવે છે, જે પછી એક્શનના પ્રકાર અને પેલોડના આધારે સ્ટેટને અપડેટ કરે છે.
એક વ્યવહારુ ઉદાહરણ: કાઉન્ટરનો અમલ
ચાલો એક સરળ ઉદાહરણથી શરૂઆત કરીએ: એક કાઉન્ટર કોમ્પોનન્ટ. આ વધુ જટિલ ઉદાહરણો પર જતા પહેલા મૂળભૂત ખ્યાલોને સમજાવે છે. આપણે એક કાઉન્ટર બનાવીશું જે વધારી, ઘટાડી અને રીસેટ કરી શકે છે:
import React, { useReducer } from 'react';
// એક્શન પ્રકારો વ્યાખ્યાયિત કરો
const INCREMENT = 'INCREMENT';
const DECREMENT = 'DECREMENT';
const RESET = 'RESET';
// રિડ્યુસર ફંક્શન વ્યાખ્યાયિત કરો
function counterReducer(state, action) {
switch (action.type) {
case INCREMENT:
return { count: state.count + 1 };
case DECREMENT:
return { count: state.count - 1 };
case RESET:
return { count: 0 };
default:
return state;
}
}
function Counter() {
// useReducer શરૂ કરો
const [state, dispatch] = useReducer(counterReducer, { count: 0 });
return (
<div>
<p>ગણતરી: {state.count}</p>
<button onClick={() => dispatch({ type: INCREMENT })}>વધારો</button>
<button onClick={() => dispatch({ type: DECREMENT })}>ઘટાડો</button>
<button onClick={() => dispatch({ type: RESET })}>રીસેટ</button>
</div>
);
}
export default Counter;
આ ઉદાહરણમાં:
- આપણે વધુ સારી જાળવણી માટે એક્શન પ્રકારોને કોન્સ્ટન્ટ તરીકે વ્યાખ્યાયિત કરીએ છીએ (
INCREMENT
,DECREMENT
,RESET
). counterReducer
ફંક્શન વર્તમાન સ્ટેટ અને એક્શન લે છે. તે એક્શનના પ્રકારના આધારે સ્ટેટને કેવી રીતે અપડેટ કરવું તે નક્કી કરવા માટેswitch
સ્ટેટમેન્ટનો ઉપયોગ કરે છે.- પ્રારંભિક સ્ટેટ
{ count: 0 }
છે. dispatch
ફંક્શનનો ઉપયોગ બટન ક્લિક હેન્ડલર્સમાં સ્ટેટ અપડેટ્સને ટ્રિગર કરવા માટે થાય છે. ઉદાહરણ તરીકે,dispatch({ type: INCREMENT })
રિડ્યુસરનેINCREMENT
પ્રકારનું એક્શન મોકલે છે.
કાઉન્ટરના ઉદાહરણને વિસ્તૃત કરવું: પેલોડ ઉમેરવું
ચાલો કાઉન્ટરને એક ચોક્કસ મૂલ્ય દ્વારા વધારવાની મંજૂરી આપવા માટે તેમાં ફેરફાર કરીએ. આ એક્શનમાં પેલોડની વિભાવનાનો પરિચય કરાવે છે:
import React, { useReducer } from 'react';
const INCREMENT = 'INCREMENT';
const DECREMENT = 'DECREMENT';
const RESET = 'RESET';
const SET_VALUE = 'SET_VALUE';
function counterReducer(state, action) {
switch (action.type) {
case INCREMENT:
return { count: state.count + action.payload };
case DECREMENT:
return { count: state.count - action.payload };
case RESET:
return { count: 0 };
case SET_VALUE:
return { count: action.payload };
default:
return state;
}
}
function Counter() {
const [state, dispatch] = useReducer(counterReducer, { count: 0 });
const [inputValue, setInputValue] = React.useState(1);
return (
<div>
<p>ગણતરી: {state.count}</p>
<button onClick={() => dispatch({ type: INCREMENT, payload: parseInt(inputValue) || 1 })}>{inputValue} દ્વારા વધારો</button>
<button onClick={() => dispatch({ type: DECREMENT, payload: parseInt(inputValue) || 1 })}>{inputValue} દ્વારા ઘટાડો</button>
<button onClick={() => dispatch({ type: RESET })}>રીસેટ</button>
<input
type="number"
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
/>
</div>
);
}
export default Counter;
આ વિસ્તૃત ઉદાહરણમાં:
- આપણે
SET_VALUE
એક્શન પ્રકાર ઉમેર્યો છે. INCREMENT
અનેDECREMENT
એક્શન્સ હવેpayload
સ્વીકારે છે, જે વધારવા અથવા ઘટાડવાની રકમનું પ્રતિનિધિત્વ કરે છે.parseInt(inputValue) || 1
એ સુનિશ્ચિત કરે છે કે મૂલ્ય એક પૂર્ણાંક છે અને જો ઇનપુટ અમાન્ય હોય તો ડિફોલ્ટ રૂપે 1 થાય છે.- આપણે એક ઇનપુટ ફીલ્ડ ઉમેર્યું છે જે વપરાશકર્તાઓને વધારો/ઘટાડો મૂલ્ય સેટ કરવાની મંજૂરી આપે છે.
useReducer
નો ઉપયોગ કરવાના ફાયદા
useReducer
પેટર્ન જટિલ સ્ટેટ મેનેજમેન્ટ માટે સીધા useState
નો ઉપયોગ કરવા પર ઘણા ફાયદાઓ પ્રદાન કરે છે:
- કેન્દ્રિય સ્ટેટ લોજિક: બધા સ્ટેટ અપડેટ્સ રિડ્યુસર ફંક્શનની અંદર હેન્ડલ કરવામાં આવે છે, જે સ્ટેટ ફેરફારોને સમજવા અને ડિબગ કરવાનું સરળ બનાવે છે.
- સુધારેલ કોડ સંગઠન: સ્ટેટ અપડેટ લોજિકને કોમ્પોનન્ટના રેન્ડરિંગ લોજિકથી અલગ કરીને, તમારો કોડ વધુ સંગઠિત અને વાંચવા યોગ્ય બને છે, જે વધુ સારી કોડ જાળવણીને પ્રોત્સાહન આપે છે.
- અનુમાનિત સ્ટેટ અપડેટ્સ: કારણ કે રિડ્યુસર્સ શુદ્ધ ફંક્શન્સ છે, તમે સરળતાથી અનુમાન કરી શકો છો કે ચોક્કસ એક્શન અને પ્રારંભિક સ્ટેટ આપેલ સ્ટેટ કેવી રીતે બદલાશે. આ ડિબગીંગ અને પરીક્ષણને ઘણું સરળ બનાવે છે.
- પ્રદર્શન ઓપ્ટિમાઇઝેશન:
useReducer
પ્રદર્શનને શ્રેષ્ઠ બનાવવામાં મદદ કરી શકે છે, ખાસ કરીને જ્યારે સ્ટેટ અપડેટ્સ ગણતરીની દ્રષ્ટિએ ખર્ચાળ હોય. જ્યારે સ્ટેટ અપડેટ લોજિક રિડ્યુસરમાં સમાયેલું હોય ત્યારે React વધુ કાર્યક્ષમ રીતે રી-રેન્ડર્સને ઓપ્ટિમાઇઝ કરી શકે છે. - પરીક્ષણક્ષમતા: રિડ્યુસર્સ શુદ્ધ ફંક્શન્સ છે, જે તેમને પરીક્ષણ કરવા માટે સરળ બનાવે છે. તમે તમારા રિડ્યુસર વિવિધ એક્શન્સ અને પ્રારંભિક સ્ટેટ્સને યોગ્ય રીતે હેન્ડલ કરે છે તેની ખાતરી કરવા માટે યુનિટ પરીક્ષણો લખી શકો છો.
- Redux ના વિકલ્પો: ઘણી એપ્લિકેશન્સ માટે,
useReducer
Redux નો એક સરળ વિકલ્પ પૂરો પાડે છે, જે અલગ લાઇબ્રેરી અને તેને ગોઠવવા અને સંચાલિત કરવાના ઓવરહેડની જરૂરિયાતને દૂર કરે છે. આ તમારા ડેવલપમેન્ટ વર્કફ્લોને સુવ્યવસ્થિત કરી શકે છે, ખાસ કરીને નાનાથી મધ્યમ કદના પ્રોજેક્ટ્સ માટે.
useReducer
નો ઉપયોગ ક્યારે કરવો
જ્યારે useReducer
નોંધપાત્ર ફાયદાઓ પ્રદાન કરે છે, તે હંમેશાં યોગ્ય પસંદગી નથી. useReducer
નો ઉપયોગ કરવાનું વિચારો જ્યારે:
- તમારી પાસે જટિલ સ્ટેટ લોજિક છે જેમાં બહુવિધ સ્ટેટ વેરિયેબલ્સ સામેલ છે.
- સ્ટેટ અપડેટ્સ પાછલા સ્ટેટ પર આધાર રાખે છે (દા.ત., ચાલુ કુલની ગણતરી કરવી).
- તમારે વધુ સારી જાળવણી માટે તમારા સ્ટેટ અપડેટ લોજિકને કેન્દ્રિત અને સંગઠિત કરવાની જરૂર છે.
- તમે તમારા સ્ટેટ અપડેટ્સની પરીક્ષણક્ષમતા અને અનુમાનક્ષમતા સુધારવા માંગો છો.
- તમે અલગ લાઇબ્રેરી રજૂ કર્યા વિના Redux-જેવી પેટર્ન શોધી રહ્યા છો.
સરળ સ્ટેટ અપડેટ્સ માટે, useState
ઘણીવાર પૂરતું અને વાપરવામાં સરળ હોય છે. નિર્ણય લેતી વખતે તમારા સ્ટેટની જટિલતા અને વૃદ્ધિની સંભવનાને ધ્યાનમાં લો.
અદ્યતન ખ્યાલો અને તકનીકો
useReducer
ને Context સાથે જોડવું
વૈશ્વિક સ્ટેટનું સંચાલન કરવા અથવા બહુવિધ કોમ્પોનન્ટ્સમાં સ્ટેટ શેર કરવા માટે, તમે useReducer
ને React ના Context API સાથે જોડી શકો છો. આ અભિગમ નાનાથી મધ્યમ કદના પ્રોજેક્ટ્સ માટે Redux કરતાં વધુ પસંદ કરવામાં આવે છે જ્યાં તમે વધારાની નિર્ભરતા દાખલ કરવા માંગતા નથી.
import React, { createContext, useReducer, useContext } from 'react';
// એક્શન પ્રકારો અને રિડ્યુસર વ્યાખ્યાયિત કરો (પહેલાની જેમ)
const INCREMENT = 'INCREMENT';
// ... (અન્ય એક્શન પ્રકારો અને counterReducer ફંક્શન)
const CounterContext = createContext();
function CounterProvider({ children }) {
const [state, dispatch] = useReducer(counterReducer, { count: 0 });
return (
<CounterContext.Provider value={{ state, dispatch }}>
{children}
</CounterContext.Provider>
);
}
function useCounter() {
return useContext(CounterContext);
}
function Counter() {
const { state, dispatch } = useCounter();
return (
<div>
<p>ગણતરી: {state.count}</p>
<button onClick={() => dispatch({ type: INCREMENT })}>વધારો</button>
</div>
);
}
function App() {
return (
<CounterProvider>
<Counter />
</CounterProvider>
);
}
export default App;
આ ઉદાહરણમાં:
- આપણે
createContext
નો ઉપયોગ કરીનેCounterContext
બનાવીએ છીએ. CounterProvider
એપ્લિકેશનને (અથવા કાઉન્ટર સ્ટેટની ઍક્સેસની જરૂર હોય તેવા ભાગોને) લપેટે છે અનેuseReducer
માંથીstate
અનેdispatch
પ્રદાન કરે છે.useCounter
હૂક ચાઈલ્ડ કોમ્પોનન્ટ્સની અંદર સંદર્ભની ઍક્સેસને સરળ બનાવે છે.Counter
જેવા કોમ્પોનન્ટ્સ હવે વૈશ્વિક સ્તરે કાઉન્ટર સ્ટેટને ઍક્સેસ અને સંશોધિત કરી શકે છે. આ સ્ટેટ અને ડિસ્પેચ ફંક્શનને બહુવિધ સ્તરના કોમ્પોનન્ટ્સ દ્વારા નીચે પસાર કરવાની જરૂરિયાતને દૂર કરે છે, જે પ્રોપ્સ મેનેજમેન્ટને સરળ બનાવે છે.
useReducer
નું પરીક્ષણ
રિડ્યુસર્સનું પરીક્ષણ કરવું સીધું છે કારણ કે તે શુદ્ધ ફંક્શન્સ છે. તમે Jest અથવા Mocha જેવા યુનિટ ટેસ્ટિંગ ફ્રેમવર્કનો ઉપયોગ કરીને રિડ્યુસર ફંક્શનને અલગથી સરળતાથી પરીક્ષણ કરી શકો છો. અહીં Jest નો ઉપયોગ કરીને એક ઉદાહરણ છે:
import { counterReducer } from './counterReducer'; // ધારો કે counterReducer એક અલગ ફાઇલમાં છે
const INCREMENT = 'INCREMENT';
describe('counterReducer', () => {
it('should increment the count', () => {
const state = { count: 0 };
const action = { type: INCREMENT };
const newState = counterReducer(state, action);
expect(newState.count).toBe(1);
});
it('should return the same state for unknown action types', () => {
const state = { count: 10 };
const action = { type: 'UNKNOWN_ACTION' };
const newState = counterReducer(state, action);
expect(newState).toBe(state); // ખાતરી કરો કે સ્ટેટ બદલાયું નથી
});
});
તમારા રિડ્યુસર્સનું પરીક્ષણ એ સુનિશ્ચિત કરે છે કે તેઓ અપેક્ષા મુજબ વર્તે છે અને તમારા સ્ટેટ લોજિકને રિફેક્ટર કરવાનું સરળ બનાવે છે. મજબૂત અને જાળવણી યોગ્ય એપ્લિકેશન્સ બનાવવા માટે આ એક નિર્ણાયક પગલું છે.
મેમોઇઝેશન સાથે પ્રદર્શનને શ્રેષ્ઠ બનાવવું
જટિલ સ્ટેટ્સ અને વારંવારના અપડેટ્સ સાથે કામ કરતી વખતે, તમારા કોમ્પોનન્ટ્સના પ્રદર્શનને શ્રેષ્ઠ બનાવવા માટે useMemo
નો ઉપયોગ કરવાનું વિચારો, ખાસ કરીને જો તમારી પાસે સ્ટેટ પર આધારિત ગણતરી કરેલ વ્યુત્પન્ન મૂલ્યો હોય. ઉદાહરણ તરીકે:
import React, { useReducer, useMemo } from 'react';
function reducer(state, action) {
// ... (રિડ્યુસર તર્ક)
}
function MyComponent() {
const [state, dispatch] = useReducer(reducer, initialState);
// એક વ્યુત્પન્ન મૂલ્યની ગણતરી કરો, તેને useMemo સાથે મેમોઇઝ કરો
const derivedValue = useMemo(() => {
// સ્ટેટ પર આધારિત ખર્ચાળ ગણતરી
return state.value1 + state.value2;
}, [state.value1, state.value2]); // નિર્ભરતા: જ્યારે આ મૂલ્યો બદલાય ત્યારે જ પુનઃગણતરી કરો
return (
<div>
<p>વ્યુત્પન્ન મૂલ્ય: {derivedValue}</p>
<button onClick={() => dispatch({ type: 'UPDATE_VALUE1', payload: 10 })}>મૂલ્ય 1 અપડેટ કરો</button>
<button onClick={() => dispatch({ type: 'UPDATE_VALUE2', payload: 20 })}>મૂલ્ય 2 અપડેટ કરો</button>
</div>
);
}
આ ઉદાહરણમાં, derivedValue
ની ગણતરી ત્યારે જ થાય છે જ્યારે state.value1
અથવા state.value2
બદલાય, દરેક રી-રેન્ડર પર બિનજરૂરી ગણતરીઓ અટકાવે છે. શ્રેષ્ઠ રેન્ડરિંગ પ્રદર્શન સુનિશ્ચિત કરવા માટે આ અભિગમ એક સામાન્ય પ્રથા છે.
વાસ્તવિક-વિશ્વના ઉદાહરણો અને ઉપયોગના કેસો
ચાલો કેટલાક વ્યવહારુ ઉદાહરણોનું અન્વેષણ કરીએ જ્યાં વૈશ્વિક પ્રેક્ષકો માટે React એપ્લિકેશન્સ બનાવવામાં useReducer
એક મૂલ્યવાન સાધન છે. નોંધ કરો કે આ ઉદાહરણો મૂળભૂત ખ્યાલોને સમજાવવા માટે સરળ બનાવવામાં આવ્યા છે. વાસ્તવિક અમલીકરણમાં વધુ જટિલ તર્ક અને નિર્ભરતા સામેલ હોઈ શકે છે.
૧. ઈ-કોમર્સ પ્રોડક્ટ ફિલ્ટર્સ
એક ઈ-કોમર્સ વેબસાઇટની કલ્પના કરો (જેમ કે એમેઝોન અથવા અલીએક્સપ્રેસ જેવી લોકપ્રિય પ્લેટફોર્મ, જે વૈશ્વિક સ્તરે ઉપલબ્ધ છે) જેમાં વિશાળ પ્રોડક્ટ કેટલોગ હોય. વપરાશકર્તાઓને વિવિધ માપદંડો (કિંમત શ્રેણી, બ્રાન્ડ, કદ, રંગ, મૂળ દેશ, વગેરે) દ્વારા ઉત્પાદનોને ફિલ્ટર કરવાની જરૂર છે. useReducer
ફિલ્ટર સ્ટેટનું સંચાલન કરવા માટે આદર્શ છે.
import React, { useReducer } from 'react';
const initialState = {
priceRange: { min: 0, max: 1000 },
brand: [], // પસંદ કરેલી બ્રાન્ડ્સનો એરે
color: [], // પસંદ કરેલા રંગોનો એરે
//... અન્ય ફિલ્ટર માપદંડો
};
function filterReducer(state, action) {
switch (action.type) {
case 'UPDATE_PRICE_RANGE':
return { ...state, priceRange: action.payload };
case 'TOGGLE_BRAND':
const brand = action.payload;
return { ...state, brand: state.brand.includes(brand) ? state.brand.filter(b => b !== brand) : [...state.brand, brand] };
case 'TOGGLE_COLOR':
// રંગ ફિલ્ટરિંગ માટે સમાન તર્ક
return { ...state, color: state.color.includes(action.payload) ? state.color.filter(c => c !== action.payload) : [...state.color, action.payload] };
// ... અન્ય ફિલ્ટર એક્શન્સ
default:
return state;
}
}
function ProductFilter() {
const [state, dispatch] = useReducer(filterReducer, initialState);
// ફિલ્ટર માપદંડો પસંદ કરવા અને ડિસ્પેચ એક્શન્સ ટ્રિગર કરવા માટે UI ઘટકો
// ઉદાહરણ તરીકે: કિંમત માટે રેન્જ ઇનપુટ, બ્રાન્ડ્સ માટે ચેકબોક્સ, વગેરે.
return (
<div>
<!-- ફિલ્ટર UI તત્વો -->
</div>
);
}
આ ઉદાહરણ બતાવે છે કે નિયંત્રિત રીતે બહુવિધ ફિલ્ટર માપદંડોને કેવી રીતે હેન્ડલ કરવું. જ્યારે કોઈ વપરાશકર્તા કોઈપણ ફિલ્ટર સેટિંગ (કિંમત, બ્રાન્ડ, વગેરે) માં ફેરફાર કરે છે, ત્યારે રિડ્યુસર તે મુજબ ફિલ્ટર સ્ટેટને અપડેટ કરે છે. ઉત્પાદનો પ્રદર્શિત કરવા માટે જવાબદાર કોમ્પોનન્ટ પછી પ્રદર્શિત ઉત્પાદનોને ફિલ્ટર કરવા માટે અપડેટેડ સ્ટેટનો ઉપયોગ કરે છે. આ પેટર્ન વૈશ્વિક ઈ-કોમર્સ પ્લેટફોર્મમાં સામાન્ય જટિલ ફિલ્ટરિંગ સિસ્ટમ્સ બનાવવાનું સમર્થન કરે છે.
૨. મલ્ટિ-સ્ટેપ ફોર્મ્સ (દા.ત., આંતરરાષ્ટ્રીય શિપિંગ ફોર્મ્સ)
ઘણી એપ્લિકેશન્સમાં મલ્ટિ-સ્ટેપ ફોર્મ્સ સામેલ હોય છે, જેમ કે આંતરરાષ્ટ્રીય શિપિંગ માટે અથવા જટિલ જરૂરિયાતો સાથે વપરાશકર્તા ખાતા બનાવવા માટે વપરાય છે. useReducer
આવા ફોર્મ્સની સ્થિતિનું સંચાલન કરવામાં શ્રેષ્ઠ છે.
import React, { useReducer } from 'react';
const initialState = {
step: 1, // ફોર્મમાં વર્તમાન પગલું
formData: {
firstName: '',
lastName: '',
address: '',
city: '',
country: '',
// ... અન્ય ફોર્મ ફીલ્ડ્સ
},
errors: {},
};
function formReducer(state, action) {
switch (action.type) {
case 'NEXT_STEP':
return { ...state, step: state.step + 1 };
case 'PREV_STEP':
return { ...state, step: state.step - 1 };
case 'UPDATE_FIELD':
return { ...state, formData: { ...state.formData, [action.payload.field]: action.payload.value } };
case 'SET_ERRORS':
return { ...state, errors: action.payload };
case 'SUBMIT_FORM':
// અહીં ફોર્મ સબમિશન તર્ક હેન્ડલ કરો, દા.ત., API કૉલ્સ
return state;
default:
return state;
}
}
function MultiStepForm() {
const [state, dispatch] = useReducer(formReducer, initialState);
// ફોર્મના દરેક પગલા માટે રેન્ડરિંગ તર્ક
// સ્ટેટમાં વર્તમાન પગલાના આધારે
const renderStep = () => {
switch (state.step) {
case 1:
return <Step1 formData={state.formData} dispatch={dispatch} />;
case 2:
return <Step2 formData={state.formData} dispatch={dispatch} />;
// ... અન્ય પગલાં
default:
return <p>અમાન્ય પગલું</p>;
}
};
return (
<div>
{renderStep()}
<!-- વર્તમાન પગલાના આધારે નેવિગેશન બટનો (આગળ, પાછળ, સબમિટ) -->
</div>
);
}
આ બતાવે છે કે વિવિધ ફોર્મ ફીલ્ડ્સ, પગલાં અને સંભવિત માન્યતા ભૂલોને એક સંરચિત અને જાળવણી યોગ્ય રીતે કેવી રીતે સંચાલિત કરવી. વપરાશકર્તા-મૈત્રીપૂર્ણ નોંધણી અથવા ચેકઆઉટ પ્રક્રિયાઓ બનાવવા માટે તે નિર્ણાયક છે, ખાસ કરીને આંતરરાષ્ટ્રીય વપરાશકર્તાઓ માટે જેઓ તેમની સ્થાનિક રિવાજો અને ફેસબુક અથવા વીચેટ જેવા વિવિધ પ્લેટફોર્મ્સ સાથેના અનુભવના આધારે જુદી જુદી અપેક્ષાઓ રાખી શકે છે.
૩. રીઅલ-ટાઇમ એપ્લિકેશન્સ (ચેટ, સહયોગ સાધનો)
useReducer
રીઅલ-ટાઇમ એપ્લિકેશન્સ, જેમ કે ગૂગલ ડૉક્સ અથવા મેસેજિંગ એપ્લિકેશન્સ જેવા સહયોગી સાધનો માટે ફાયદાકારક છે. તે સંદેશા પ્રાપ્ત કરવા, વપરાશકર્તા જોડાવા/છોડવા અને કનેક્શન સ્થિતિ જેવી ઘટનાઓને હેન્ડલ કરે છે, ખાતરી કરે છે કે UI જરૂર મુજબ અપડેટ થાય છે.
import React, { useReducer, useEffect } from 'react';
const initialState = {
messages: [],
users: [],
connectionStatus: 'connecting',
};
function chatReducer(state, action) {
switch (action.type) {
case 'RECEIVE_MESSAGE':
return { ...state, messages: [...state.messages, action.payload] };
case 'USER_JOINED':
return { ...state, users: [...state.users, action.payload] };
case 'USER_LEFT':
return { ...state, users: state.users.filter(user => user.id !== action.payload.id) };
case 'SET_CONNECTION_STATUS':
return { ...state, connectionStatus: action.payload };
default:
return state;
}
}
function ChatRoom() {
const [state, dispatch] = useReducer(chatReducer, initialState);
useEffect(() => {
// WebSocket કનેક્શન સ્થાપિત કરો (ઉદાહરણ):
const socket = new WebSocket('wss://your-websocket-server.com');
socket.onopen = () => dispatch({ type: 'SET_CONNECTION_STATUS', payload: 'connected' });
socket.onmessage = (event) => dispatch({ type: 'RECEIVE_MESSAGE', payload: JSON.parse(event.data) });
socket.onclose = () => dispatch({ type: 'SET_CONNECTION_STATUS', payload: 'disconnected' });
return () => socket.close(); // અનમાઉન્ટ પર સફાઈ
}, []);
// સ્ટેટના આધારે સંદેશાઓ, વપરાશકર્તા સૂચિ અને કનેક્શન સ્થિતિ રેન્ડર કરો
return (
<div>
<p>કનેક્શન સ્થિતિ: {state.connectionStatus}</p>
<!-- સંદેશાઓ, વપરાશકર્તા સૂચિ અને સંદેશા મોકલવા માટે UI -->
</div>
);
}
આ ઉદાહરણ રીઅલ-ટાઇમ ચેટનું સંચાલન કરવા માટેનો આધાર પૂરો પાડે છે. સ્ટેટ સંદેશ સંગ્રહ, હાલમાં ચેટમાં રહેલા વપરાશકર્તાઓ અને કનેક્શન સ્થિતિને હેન્ડલ કરે છે. useEffect
હૂક WebSocket કનેક્શન સ્થાપિત કરવા અને આવનારા સંદેશાઓને હેન્ડલ કરવા માટે જવાબદાર છે. આ અભિગમ એક પ્રતિભાવશીલ અને ગતિશીલ વપરાશકર્તા ઇન્ટરફેસ બનાવે છે જે વિશ્વભરના વપરાશકર્તાઓને પૂરો પાડે છે.
useReducer
નો ઉપયોગ કરવા માટે શ્રેષ્ઠ પ્રથાઓ
useReducer
નો અસરકારક રીતે ઉપયોગ કરવા અને જાળવણી યોગ્ય એપ્લિકેશન્સ બનાવવા માટે, આ શ્રેષ્ઠ પ્રથાઓનો વિચાર કરો:
- એક્શન પ્રકારો વ્યાખ્યાયિત કરો: તમારા એક્શન પ્રકારો માટે કોન્સ્ટન્ટ્સનો ઉપયોગ કરો (દા.ત.,
const INCREMENT = 'INCREMENT';
). આ ટાઇપોને ટાળવાનું સરળ બનાવે છે અને કોડ વાંચવાની ક્ષમતા સુધારે છે. - રિડ્યુસર્સને શુદ્ધ રાખો: રિડ્યુસર્સ શુદ્ધ ફંક્શન્સ હોવા જોઈએ. તેમની કોઈ આડઅસર ન હોવી જોઈએ, જેમ કે વૈશ્વિક વેરિયેબલ્સમાં ફેરફાર કરવો અથવા API કૉલ્સ કરવા. રિડ્યુસર ફક્ત વર્તમાન સ્ટેટ અને એક્શનના આધારે નવા સ્ટેટની ગણતરી અને પરત કરવું જોઈએ.
- અપરિવર્તનશીલ સ્ટેટ અપડેટ્સ: હંમેશા સ્ટેટને અપરિવર્તનશીલ રીતે અપડેટ કરો. સ્ટેટ ઑબ્જેક્ટને સીધું સંશોધિત કરશો નહીં. તેના બદલે, સ્પ્રેડ સિન્ટેક્સ (
...
) અથવાObject.assign()
નો ઉપયોગ કરીને ઇચ્છિત ફેરફારો સાથે એક નવો ઑબ્જેક્ટ બનાવો. આ અનપેક્ષિત વર્તનને અટકાવે છે અને સરળ ડિબગીંગને સક્ષમ કરે છે. - પેલોડ્સ સાથે એક્શન્સની રચના કરો: રિડ્યુસરને ડેટા પસાર કરવા માટે તમારા એક્શન્સમાં
payload
પ્રોપર્ટીનો ઉપયોગ કરો. આ તમારા એક્શન્સને વધુ લવચીક બનાવે છે અને તમને વ્યાપક શ્રેણીના સ્ટેટ અપડેટ્સને હેન્ડલ કરવાની મંજૂરી આપે છે. - વૈશ્વિક સ્ટેટ માટે Context API નો ઉપયોગ કરો: જો તમારું સ્ટેટ બહુવિધ કોમ્પોનન્ટ્સમાં શેર કરવાની જરૂર હોય, તો
useReducer
ને Context API સાથે જોડો. આ Redux જેવી બાહ્ય નિર્ભરતા દાખલ કર્યા વિના વૈશ્વિક સ્ટેટનું સંચાલન કરવાની એક સ્વચ્છ અને કાર્યક્ષમ રીત પ્રદાન કરે છે. - જટિલ તર્ક માટે રિડ્યુસર્સને વિભાજીત કરો: જટિલ સ્ટેટ તર્ક માટે, તમારા રિડ્યુસરને નાના, વધુ વ્યવસ્થાપિત ફંક્શન્સમાં વિભાજીત કરવાનું વિચારો. આ વાંચવાની ક્ષમતા અને જાળવણીક્ષમતા વધારે છે. તમે રિડ્યુસર ફંક્શનના ચોક્કસ વિભાગમાં સંબંધિત એક્શન્સને પણ જૂથબદ્ધ કરી શકો છો.
- તમારા રિડ્યુસર્સનું પરીક્ષણ કરો: તમારા રિડ્યુસર્સ માટે યુનિટ પરીક્ષણો લખો જેથી ખાતરી કરી શકાય કે તેઓ વિવિધ એક્શન્સ અને પ્રારંભિક સ્ટેટ્સને યોગ્ય રીતે હેન્ડલ કરે છે. કોડની ગુણવત્તા સુનિશ્ચિત કરવા અને રીગ્રેશન અટકાવવા માટે આ નિર્ણાયક છે. પરીક્ષણોએ સ્ટેટ ફેરફારોના તમામ સંભવિત દૃશ્યોને આવરી લેવા જોઈએ.
- પ્રદર્શન ઓપ્ટિમાઇઝેશનનો વિચાર કરો: જો તમારા સ્ટેટ અપડેટ્સ ગણતરીની દ્રષ્ટિએ ખર્ચાળ હોય અથવા વારંવાર રી-રેન્ડર્સ ટ્રિગર કરતા હોય, તો તમારા કોમ્પોનન્ટ્સના પ્રદર્શનને શ્રેષ્ઠ બનાવવા માટે
useMemo
જેવી મેમોઇઝેશન તકનીકોનો ઉપયોગ કરો. - દસ્તાવેજીકરણ: સ્ટેટ, એક્શન્સ અને તમારા રિડ્યુસરના હેતુ વિશે સ્પષ્ટ દસ્તાવેજીકરણ પ્રદાન કરો. આ અન્ય ડેવલપર્સને તમારા કોડને સમજવા અને જાળવવામાં મદદ કરે છે.
નિષ્કર્ષ
useReducer
હૂક React એપ્લિકેશન્સમાં જટિલ સ્ટેટનું સંચાલન કરવા માટે એક શક્તિશાળી અને બહુમુખી સાધન છે. તે કેન્દ્રિય સ્ટેટ લોજિક, સુધારેલ કોડ સંગઠન અને ઉન્નત પરીક્ષણક્ષમતા સહિત અસંખ્ય ફાયદાઓ પ્રદાન કરે છે. શ્રેષ્ઠ પ્રથાઓનું પાલન કરીને અને તેના મૂળભૂત ખ્યાલોને સમજીને, તમે વધુ મજબૂત, જાળવણી યોગ્ય અને કાર્યક્ષમ React એપ્લિકેશન્સ બનાવવા માટે useReducer
નો લાભ લઈ શકો છો. આ પેટર્ન તમને જટિલ સ્ટેટ મેનેજમેન્ટ પડકારોનો અસરકારક રીતે સામનો કરવા માટે સશક્ત બનાવે છે, જે તમને વૈશ્વિક-તૈયાર એપ્લિકેશન્સ બનાવવાની મંજૂરી આપે છે જે વિશ્વભરમાં સીમલેસ વપરાશકર્તા અનુભવો પ્રદાન કરે છે.
જેમ જેમ તમે React ડેવલપમેન્ટમાં ઊંડા ઉતરશો, તેમ તેમ useReducer
પેટર્નને તમારા ટૂલકિટમાં સામેલ કરવાથી નિઃશંકપણે સ્વચ્છ, વધુ માપી શકાય તેવા અને સરળતાથી જાળવી શકાય તેવા કોડબેઝ તરફ દોરી જશે. તમારી એપ્લિકેશનની ચોક્કસ જરૂરિયાતોને હંમેશા ધ્યાનમાં રાખવાનું યાદ રાખો અને દરેક પરિસ્થિતિ માટે સ્ટેટ મેનેજમેન્ટનો શ્રેષ્ઠ અભિગમ પસંદ કરો. હેપ્પી કોડિંગ!