રિએક્ટના કમ્પોનન્ટ આર્કિટેક્ચરનું ઊંડાણપૂર્વક વિશ્લેષણ, જેમાં કમ્પોઝિશન અને ઇન્હેરિટન્સની તુલના છે. જાણો શા માટે રિએક્ટ કમ્પોઝિશનને પસંદ કરે છે અને સ્કેલેબલ, પુનઃઉપયોગી કમ્પોનન્ટ્સ બનાવવા માટે HOCs, રેન્ડર પ્રોપ્સ અને હુક્સ જેવા પેટર્નનું અન્વેષણ કરો.
રિએક્ટ કમ્પોનન્ટ આર્કિટેક્ચર: શા માટે કમ્પોઝિશન ઇન્હેરિટન્સ પર વિજય મેળવે છે
સોફ્ટવેર ડેવલપમેન્ટની દુનિયામાં, આર્કિટેક્ચર સર્વોપરી છે. આપણે જે રીતે આપણા કોડની રચના કરીએ છીએ તે તેની સ્કેલેબિલિટી, જાળવણીક્ષમતા અને પુનઃઉપયોગીતા નક્કી કરે છે. રિએક્ટ સાથે કામ કરતા ડેવલપર્સ માટે, સૌથી મૂળભૂત આર્કિટેક્ચરલ નિર્ણયો પૈકીનો એક એ છે કે કમ્પોનન્ટ્સ વચ્ચે લોજિક અને UI કેવી રીતે શેર કરવું. આ આપણને ઓબ્જેક્ટ-ઓરિએન્ટેડ પ્રોગ્રામિંગમાં એક ક્લાસિક ચર્ચા તરફ લઈ જાય છે, જેને રિએક્ટની કમ્પોનન્ટ-આધારિત દુનિયા માટે પુનઃકલ્પિત કરવામાં આવી છે: કમ્પોઝિશન વિ. ઇન્હેરિટન્સ.
જો તમે જાવા અથવા C++ જેવી ક્લાસિકલ ઓબ્જેક્ટ-ઓરિએન્ટેડ ભાષાઓની પૃષ્ઠભૂમિમાંથી આવો છો, તો ઇન્હેરિટન્સ એક કુદરતી પ્રથમ પસંદગી જેવું લાગી શકે છે. તે 'is-a' સંબંધો બનાવવા માટે એક શક્તિશાળી ખ્યાલ છે. જોકે, સત્તાવાર રિએક્ટ દસ્તાવેજીકરણ એક સ્પષ્ટ અને મજબૂત ભલામણ આપે છે: "ફેસબુક પર, અમે હજારો કમ્પોનન્ટ્સમાં રિએક્ટનો ઉપયોગ કરીએ છીએ, અને અમને એવો કોઈ ઉપયોગ કેસ મળ્યો નથી જ્યાં અમે કમ્પોનન્ટ ઇન્હેરિટન્સ હાઇરાર્કી બનાવવાની ભલામણ કરીએ."
આ પોસ્ટ આ આર્કિટેક્ચરલ પસંદગીનું વ્યાપક સંશોધન પ્રદાન કરશે. આપણે રિએક્ટના સંદર્ભમાં ઇન્હેરિટન્સ અને કમ્પોઝિશનનો અર્થ શું છે તે ખોલીશું, શા માટે કમ્પોઝિશન એ ઇડિઓમેટિક અને શ્રેષ્ઠ અભિગમ છે તે દર્શાવીશું, અને શક્તિશાળી પેટર્નનું અન્વેષણ કરીશું—હાયર-ઓર્ડર કમ્પોનન્ટ્સથી લઈને આધુનિક હુક્સ સુધી—જે વૈશ્વિક પ્રેક્ષકો માટે મજબૂત અને લવચીક એપ્લિકેશન્સ બનાવવા માટે કમ્પોઝિશનને ડેવલપરનો શ્રેષ્ઠ મિત્ર બનાવે છે.
જૂની પદ્ધતિને સમજવું: ઇન્હેરિટન્સ શું છે?
ઇન્હેરિટન્સ એ ઓબ્જેક્ટ-ઓરિએન્ટેડ પ્રોગ્રામિંગ (OOP) નો મુખ્ય આધારસ્તંભ છે. તે નવા ક્લાસ (સબક્લાસ અથવા ચાઇલ્ડ) ને હાલના ક્લાસ (સુપરક્લાસ અથવા પેરેન્ટ) ના ગુણધર્મો અને મેથડ્સ મેળવવાની મંજૂરી આપે છે. આ એક ચુસ્તપણે જોડાયેલ 'is-a' સંબંધ બનાવે છે. ઉદાહરણ તરીકે, GoldenRetriever
એક Dog
છે, જે એક Animal
છે.
નોન-રિએક્ટ સંદર્ભમાં ઇન્હેરિટન્સ
ચાલો આ ખ્યાલને મજબૂત કરવા માટે એક સરળ જાવાસ્ક્રિપ્ટ ક્લાસ ઉદાહરણ જોઈએ:
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a noise.`);
}
}
class Dog extends Animal {
constructor(name, breed) {
super(name); // પેરેન્ટ કન્સ્ટ્રક્ટરને કૉલ કરે છે
this.breed = breed;
}
speak() { // પેરેન્ટ મેથડને ઓવરરાઇડ કરે છે
console.log(`${this.name} barks.`);
}
fetch() {
console.log(`${this.name} is fetching the ball!`);
}
}
const myDog = new Dog('Buddy', 'Golden Retriever');
myDog.speak(); // આઉટપુટ: "Buddy barks."
myDog.fetch(); // આઉટપુટ: "Buddy is fetching the ball!"
આ મોડેલમાં, Dog
ક્લાસ આપોઆપ Animal
માંથી name
પ્રોપર્ટી અને speak
મેથડ મેળવે છે. તે પોતાની મેથડ્સ (fetch
) પણ ઉમેરી શકે છે અને હાલની મેથડ્સને ઓવરરાઇડ કરી શકે છે. આ એક કઠોર હાઇરાર્કી બનાવે છે.
રિએક્ટમાં ઇન્હેરિટન્સ શા માટે નિષ્ફળ જાય છે
જ્યારે આ 'is-a' મોડેલ કેટલાક ડેટા સ્ટ્રક્ચર્સ માટે કામ કરે છે, તે રિએક્ટમાં UI કમ્પોનન્ટ્સ પર લાગુ કરવામાં આવે ત્યારે નોંધપાત્ર સમસ્યાઓ ઊભી કરે છે:
- ટાઇટ કપલિંગ: જ્યારે કોઈ કમ્પોનન્ટ બેઝ કમ્પોનન્ટમાંથી ઇન્હેરિટ કરે છે, ત્યારે તે તેના પેરેન્ટના ઇમ્પ્લીમેન્ટેશન સાથે ચુસ્તપણે જોડાઈ જાય છે. બેઝ કમ્પોનન્ટમાં ફેરફાર ચેઇનમાં નીચેના અનેક ચાઇલ્ડ કમ્પોનન્ટ્સને અણધારી રીતે તોડી શકે છે. આ રિફેક્ટરિંગ અને જાળવણીને એક નાજુક પ્રક્રિયા બનાવે છે.
- બિન-લવચીક લોજિક શેરિંગ: જો તમે કોઈ ચોક્કસ કાર્યક્ષમતા, જેમ કે ડેટા ફેચિંગ, એવા કમ્પોનન્ટ્સ સાથે શેર કરવા માંગતા હોવ જે સમાન 'is-a' હાઇરાર્કીમાં ફિટ ન થતા હોય તો શું? ઉદાહરણ તરીકે,
UserProfile
અનેProductList
બંનેને ડેટા ફેચ કરવાની જરૂર પડી શકે છે, પરંતુ તેમના માટે સામાન્યDataFetchingComponent
માંથી ઇન્હેરિટ કરવું તે કોઈ અર્થપૂર્ણ નથી. - પ્રોપ-ડ્રિલિંગની સમસ્યા: ઊંડી ઇન્હેરિટન્સ ચેઇનમાં, ટોપ-લેવલ કમ્પોનન્ટમાંથી ઊંડા નેસ્ટેડ ચાઇલ્ડ સુધી પ્રોપ્સ પસાર કરવું મુશ્કેલ બને છે. તમારે એવા મધ્યવર્તી કમ્પોનન્ટ્સ દ્વારા પ્રોપ્સ પસાર કરવા પડી શકે છે જે તેનો ઉપયોગ પણ કરતા નથી, જે ગૂંચવણભર્યા અને ફૂલેલા કોડ તરફ દોરી જાય છે.
- "ગોરિલા-બનાના સમસ્યા": OOP નિષ્ણાત જો આર્મસ્ટ્રોંગનું એક પ્રખ્યાત અવતરણ આ મુદ્દાને સંપૂર્ણ રીતે વર્ણવે છે: "તમારે એક કેળું જોઈતું હતું, પરંતુ તમને જે મળ્યું તે એક ગોરિલો હતો જે કેળું અને આખું જંગલ પકડીને બેઠો હતો." ઇન્હેરિટન્સ સાથે, તમે ફક્ત તમને જોઈતી કાર્યક્ષમતાનો ટુકડો મેળવી શકતા નથી; તમને તેની સાથે સંપૂર્ણ સુપરક્લાસ લાવવાની ફરજ પાડવામાં આવે છે.
આ મુદ્દાઓને કારણે, રિએક્ટ ટીમે લાઇબ્રેરીને વધુ લવચીક અને શક્તિશાળી પેરાડાઈમની આસપાસ ડિઝાઇન કરી છે: કમ્પોઝિશન.
રિએક્ટની રીત અપનાવવી: કમ્પોઝિશનની શક્તિ
કમ્પોઝિશન એ એક ડિઝાઇન સિદ્ધાંત છે જે 'has-a' અથવા 'uses-a' સંબંધને પસંદ કરે છે. એક કમ્પોનન્ટ બીજા કમ્પોનન્ટ હોવાને બદલે, તે અન્ય કમ્પોનન્ટ્સ ધરાવે છે અથવા તેમની કાર્યક્ષમતાનો ઉપયોગ કરે છે. કમ્પોનન્ટ્સને બિલ્ડિંગ બ્લોક્સ—જેમ કે LEGO ઇંટો—તરીકે ગણવામાં આવે છે જેને કઠોર હાઇરાર્કીમાં બંધાયા વિના જટિલ UIs બનાવવા માટે વિવિધ રીતે જોડી શકાય છે.
રિએક્ટનું કમ્પોઝિશનલ મોડેલ અતિ બહુમુખી છે, અને તે ઘણા મુખ્ય પેટર્નમાં પ્રગટ થાય છે. ચાલો આપણે તેમને સૌથી મૂળભૂતથી લઈને સૌથી આધુનિક અને શક્તિશાળી સુધી અન્વેષણ કરીએ.
તકનીક 1: `props.children` સાથે કન્ટેનમેન્ટ
કમ્પોઝિશનનું સૌથી સીધું સ્વરૂપ કન્ટેનમેન્ટ છે. આ તે છે જ્યાં એક કમ્પોનન્ટ એક સામાન્ય કન્ટેનર અથવા 'બોક્સ' તરીકે કાર્ય કરે છે, અને તેની સામગ્રી પેરેન્ટ કમ્પોનન્ટમાંથી પસાર કરવામાં આવે છે. રિએક્ટ પાસે આ માટે એક ખાસ, બિલ્ટ-ઇન પ્રોપ છે: props.children
.
કલ્પના કરો કે તમારે `Card` કમ્પોનન્ટની જરૂર છે જે કોઈપણ સામગ્રીને સુસંગત બોર્ડર અને શેડો સાથે લપેટી શકે. ઇન્હેરિટન્સ દ્વારા `TextCard`, `ImageCard`, અને `ProfileCard` જેવા વેરિઅન્ટ્સ બનાવવાને બદલે, તમે એક સામાન્ય `Card` કમ્પોનન્ટ બનાવો છો.
// Card.js - એક સામાન્ય કન્ટેનર કમ્પોનન્ટ
function Card(props) {
return (
<div className="card">
{props.children}
</div>
);
}
// App.js - Card કમ્પોનન્ટનો ઉપયોગ
function App() {
return (
<div>
<Card>
<h1>Welcome!</h1>
<p>This content is inside a Card component.</p>
</Card>
<Card>
<img src="/path/to/image.jpg" alt="An example image" />
<p>This is an image card.</p>
</Card>
</div>
);
}
અહીં, Card
કમ્પોનન્ટ જાણતું નથી કે તેમાં શું છે અથવા તેની પરવા કરતું નથી. તે ફક્ત રેપર સ્ટાઇલિંગ પ્રદાન કરે છે. ઓપનિંગ અને ક્લોઝિંગ <Card>
ટેગ્સ વચ્ચેની સામગ્રી આપોઆપ props.children
તરીકે પસાર થાય છે. આ ડિકપલિંગ અને પુનઃઉપયોગીતાનું એક સુંદર ઉદાહરણ છે.
તકનીક 2: પ્રોપ્સ સાથે સ્પેશિયલાઇઝેશન
કેટલીકવાર, એક કમ્પોનન્ટને અન્ય કમ્પોનન્ટ્સ દ્વારા ભરવા માટે બહુવિધ 'છિદ્રો'ની જરૂર પડે છે. જ્યારે તમે `props.children` નો ઉપયોગ કરી શકો છો, ત્યારે વધુ સ્પષ્ટ અને સંરચિત રીત એ છે કે કમ્પોનન્ટ્સને નિયમિત પ્રોપ્સ તરીકે પસાર કરવા. આ પેટર્નને ઘણીવાર સ્પેશિયલાઇઝેશન કહેવામાં આવે છે.
એક `Modal` કમ્પોનન્ટનો વિચાર કરો. એક મોડલમાં સામાન્ય રીતે ટાઇટલ વિભાગ, કન્ટેન્ટ વિભાગ, અને એક્શન્સ વિભાગ (જેમ કે "Confirm" અથવા "Cancel" બટનો સાથે) હોય છે. આપણે આપણા `Modal` ને આ વિભાગોને પ્રોપ્સ તરીકે સ્વીકારવા માટે ડિઝાઇન કરી શકીએ છીએ.
// Modal.js - એક વધુ વિશિષ્ટ કન્ટેનર
function Modal(props) {
return (
<div className="modal-backdrop">
<div className="modal-content">
<div className="modal-header">{props.title}</div>
<div className="modal-body">{props.body}</div>
<div className="modal-footer">{props.actions}</div>
</div>
</div>
);
}
// App.js - વિશિષ્ટ કમ્પોનન્ટ્સ સાથે Modal નો ઉપયોગ
function App() {
const confirmationTitle = <h2>Confirm Action</h2>;
const confirmationBody = <p>Are you sure you want to proceed with this action?</p>;
const confirmationActions = (
<div>
<button>Confirm</button>
<button>Cancel</button>
</div>
);
return (
<Modal
title={confirmationTitle}
body={confirmationBody}
actions={confirmationActions}
/>
);
}
આ ઉદાહરણમાં, Modal
એક અત્યંત પુનઃઉપયોગી લેઆઉટ કમ્પોનન્ટ છે. આપણે તેના `title`, `body`, અને `actions` માટે વિશિષ્ટ JSX તત્વો પસાર કરીને તેને વિશેષ બનાવીએ છીએ. આ `ConfirmationModal` અને `WarningModal` સબક્લાસ બનાવવા કરતાં ઘણું વધુ લવચીક છે. આપણે જરૂરિયાત મુજબ ફક્ત `Modal` ને વિવિધ સામગ્રી સાથે કમ્પોઝ કરીએ છીએ.
તકનીક 3: હાયર-ઓર્ડર કમ્પોનન્ટ્સ (HOCs)
નોન-UI લોજિક, જેમ કે ડેટા ફેચિંગ, ઓથેન્ટિકેશન, અથવા લોગિંગ, શેર કરવા માટે, રિએક્ટ ડેવલપર્સ ઐતિહાસિક રીતે હાયર-ઓર્ડર કમ્પોનન્ટ્સ (HOCs) નામના પેટર્ન તરફ વળ્યા હતા. જોકે આધુનિક રિએક્ટમાં હુક્સ દ્વારા તેને મોટાભાગે બદલી દેવામાં આવ્યું છે, તેમ છતાં તેને સમજવું મહત્વપૂર્ણ છે કારણ કે તે રિએક્ટની કમ્પોઝિશન ગાથામાં એક મુખ્ય ઉત્ક્રાંતિનું પગલું દર્શાવે છે અને હજી પણ ઘણા કોડબેઝમાં અસ્તિત્વ ધરાવે છે.
HOC એ એક ફંક્શન છે જે એક કમ્પોનન્ટને આર્ગ્યુમેન્ટ તરીકે લે છે અને એક નવું, ઉન્નત કમ્પોનન્ટ પરત કરે છે.
ચાલો આપણે `withLogger` નામનું એક HOC બનાવીએ જે જ્યારે પણ અપડેટ થાય ત્યારે કમ્પોનન્ટના પ્રોપ્સને લોગ કરે. આ ડિબગિંગ માટે ઉપયોગી છે.
// withLogger.js - HOC
import React, { useEffect } from 'react';
function withLogger(WrappedComponent) {
// તે એક નવું કમ્પોનન્ટ પરત કરે છે...
return function EnhancedComponent(props) {
useEffect(() => {
console.log('Component updated with new props:', props);
}, [props]);
// ... જે મૂળ કમ્પોનન્ટને મૂળ પ્રોપ્સ સાથે રેન્ડર કરે છે.
return <WrappedComponent {...props} />;
};
}
// MyComponent.js - ઉન્નત કરવા માટેનો કમ્પોનન્ટ
function MyComponent({ name, age }) {
return (
<div>
<h1>Hello, {name}!</h1>
<p>You are {age} years old.</p>
</div>
);
}
// ઉન્નત કમ્પોનન્ટને એક્સપોર્ટ કરવું
export default withLogger(MyComponent);
withLogger
ફંક્શન MyComponent
ને લપેટે છે, તેને MyComponent
ના આંતરિક કોડમાં ફેરફાર કર્યા વિના નવી લોગિંગ ક્ષમતાઓ આપે છે. આપણે આ જ HOC ને અન્ય કોઈ પણ કમ્પોનન્ટ પર લાગુ કરી શકીએ છીએ જેથી તેને સમાન લોગિંગ સુવિધા મળે.
HOCs સાથેના પડકારો:
- રેપર હેલ (Wrapper Hell): એક જ કમ્પોનન્ટ પર બહુવિધ HOCs લાગુ કરવાથી રિએક્ટ DevTools માં ઊંડા નેસ્ટેડ કમ્પોનન્ટ્સ પરિણમી શકે છે (દા.ત., `withAuth(withRouter(withLogger(MyComponent)))`), જે ડિબગિંગને મુશ્કેલ બનાવે છે.
- પ્રોપ નેમિંગની ટક્કર: જો કોઈ HOC એવો પ્રોપ (દા.ત., `data`) ઇન્જેક્ટ કરે છે જેનો ઉપયોગ રેપ કરેલા કમ્પોનન્ટ દ્વારા પહેલેથી જ કરવામાં આવે છે, તો તે આકસ્મિક રીતે ઓવરરાઇટ થઈ શકે છે.
- અવ્યક્ત લોજિક: કમ્પોનન્ટના કોડ પરથી હંમેશા સ્પષ્ટ નથી હોતું કે તેના પ્રોપ્સ ક્યાંથી આવી રહ્યા છે. લોજિક HOC ની અંદર છુપાયેલું હોય છે.
તકનીક 4: રેન્ડર પ્રોપ્સ
રેન્ડર પ્રોપ પેટર્ન HOCs ની કેટલીક ખામીઓના ઉકેલ તરીકે ઉભરી આવ્યું. તે લોજિક શેર કરવાની વધુ સ્પષ્ટ રીત પ્રદાન કરે છે.
રેન્ડર પ્રોપ ધરાવતો કમ્પોનન્ટ પ્રોપ તરીકે એક ફંક્શન લે છે (જેનું નામ સામાન્ય રીતે `render` હોય છે) અને તે ફંક્શનને કૉલ કરીને નક્કી કરે છે કે શું રેન્ડર કરવું, અને તેને આર્ગ્યુમેન્ટ તરીકે કોઈ પણ સ્ટેટ અથવા લોજિક પાસ કરે છે.
ચાલો આપણે `MouseTracker` કમ્પોનન્ટ બનાવીએ જે માઉસના X અને Y કોઓર્ડિનેટ્સને ટ્રેક કરે છે અને જે પણ કમ્પોનન્ટ તેનો ઉપયોગ કરવા માંગે છે તેને ઉપલબ્ધ કરાવે છે.
// MouseTracker.js - રેન્ડર પ્રોપ સાથેનો કમ્પોનન્ટ
import React, { useState, useEffect } from 'react';
function MouseTracker({ render }) {
const [position, setPosition] = useState({ x: 0, y: 0 });
const handleMouseMove = (event) => {
setPosition({ x: event.clientX, y: event.clientY });
};
useEffect(() => {
window.addEventListener('mousemove', handleMouseMove);
return () => {
window.removeEventListener('mousemove', handleMouseMove);
};
}, []);
// સ્ટેટ સાથે રેન્ડર ફંક્શનને કૉલ કરો
return render(position);
}
// App.js - MouseTracker નો ઉપયોગ
function App() {
return (
<div>
<h1>Move your mouse around!</h1>
<MouseTracker
render={mousePosition => (
<p>The current mouse position is ({mousePosition.x}, {mousePosition.y})</p>
)}
/>
</div>
);
}
અહીં, `MouseTracker` માઉસની હલચલનને ટ્રેક કરવા માટેના તમામ લોજિકને સમાવે છે. તે પોતાની રીતે કંઈપણ રેન્ડર કરતું નથી. તેના બદલે, તે રેન્ડરિંગ લોજિકને તેના `render` પ્રોપને સોંપે છે. આ HOCs કરતાં વધુ સ્પષ્ટ છે કારણ કે તમે JSX ની અંદર જ જોઈ શકો છો કે `mousePosition` ડેટા ક્યાંથી આવી રહ્યો છે.
`children` પ્રોપનો ઉપયોગ ફંક્શન તરીકે પણ થઈ શકે છે, જે આ પેટર્નનું એક સામાન્ય અને સુંદર વેરિએશન છે:
// children નો ફંક્શન તરીકે ઉપયોગ
<MouseTracker>
{mousePosition => (
<p>The current mouse position is ({mousePosition.x}, {mousePosition.y})</p>
)}
</MouseTracker>
તકનીક 5: હુક્સ (આધુનિક અને પસંદગીની પદ્ધતિ)
રિએક્ટ 16.8 માં રજૂ કરાયેલા, હુક્સે આપણે રિએક્ટ કમ્પોનન્ટ્સ લખવાની રીતમાં ક્રાંતિ લાવી. તે તમને ફંક્શનલ કમ્પોનન્ટ્સમાં સ્ટેટ અને અન્ય રિએક્ટ સુવિધાઓનો ઉપયોગ કરવાની મંજૂરી આપે છે. સૌથી અગત્યનું, કસ્ટમ હુક્સ કમ્પોનન્ટ્સ વચ્ચે સ્ટેટફુલ લોજિક શેર કરવા માટે સૌથી ઉત્તમ અને સીધો ઉકેલ પૂરો પાડે છે.
હુક્સ HOCs અને રેન્ડર પ્રોપ્સની સમસ્યાઓને વધુ સ્વચ્છ રીતે હલ કરે છે. ચાલો આપણા `MouseTracker` ઉદાહરણને `useMousePosition` નામના કસ્ટમ હુક્સમાં રિફેક્ટર કરીએ.
// hooks/useMousePosition.js - એક કસ્ટમ હૂક
import { useState, useEffect } from 'react';
export function useMousePosition() {
const [position, setPosition] = useState({ x: 0, y: 0 });
useEffect(() => {
const handleMouseMove = (event) => {
setPosition({ x: event.clientX, y: event.clientY });
};
window.addEventListener('mousemove', handleMouseMove);
return () => {
window.removeEventListener('mousemove', handleMouseMove);
};
}, []); // ખાલી ડિપેન્ડન્સી એરેનો અર્થ એ છે કે આ ઇફેક્ટ માત્ર એક જ વાર ચાલે છે
return position;
}
// DisplayMousePosition.js - હૂકનો ઉપયોગ કરતો કમ્પોનન્ટ
import { useMousePosition } from './hooks/useMousePosition';
function DisplayMousePosition() {
const position = useMousePosition(); // ફક્ત હૂકને કૉલ કરો!
return (
<p>
The mouse position is ({position.x}, {position.y})
</p>
);
}
// અન્ય કમ્પોનન્ટ, કદાચ એક ઇન્ટરેક્ટિવ તત્વ
import { useMousePosition } from './hooks/useMousePosition';
function InteractiveBox() {
const { x, y } = useMousePosition();
const style = {
position: 'absolute',
top: y - 25, // કર્સર પર બોક્સને કેન્દ્રમાં રાખો
left: x - 25,
width: '50px',
height: '50px',
backgroundColor: 'lightblue',
};
return <div style={style} />;
}
આ એક મોટો સુધારો છે. અહીં કોઈ 'રેપર હેલ' નથી, કોઈ પ્રોપ નેમિંગની ટક્કર નથી, અને કોઈ જટિલ રેન્ડર પ્રોપ ફંક્શન્સ નથી. લોજિક સંપૂર્ણપણે એક પુનઃઉપયોગી ફંક્શન (`useMousePosition`) માં ડિકપલ થયેલું છે, અને કોઈપણ કમ્પોનન્ટ કોડની એક જ, સ્પષ્ટ લાઇન સાથે તે સ્ટેટફુલ લોજિકમાં 'હૂક' કરી શકે છે. કસ્ટમ હુક્સ આધુનિક રિએક્ટમાં કમ્પોઝિશનની અંતિમ અભિવ્યક્તિ છે, જે તમને તમારા પોતાના પુનઃઉપયોગી લોજિક બ્લોક્સની લાઇબ્રેરી બનાવવાની મંજૂરી આપે છે.
ઝડપી સરખામણી: રિએક્ટમાં કમ્પોઝિશન વિ. ઇન્હેરિટન્સ
રિએક્ટના સંદર્ભમાં મુખ્ય તફાવતોનો સારાંશ આપવા માટે, અહીં એક સીધી સરખામણી છે:
પાસું | ઇન્હેરિટન્સ (રિએક્ટમાં એન્ટી-પેટર્ન) | કમ્પોઝિશન (રિએક્ટમાં પસંદગીની પદ્ધતિ) |
---|---|---|
સંબંધ | 'is-a' સંબંધ. એક વિશિષ્ટ કમ્પોનન્ટ બેઝ કમ્પોનન્ટનું એક સંસ્કરણ છે. | 'has-a' અથવા 'uses-a' સંબંધ. એક જટિલ કમ્પોનન્ટ નાના કમ્પોનન્ટ્સ ધરાવે છે અથવા શેર્ડ લોજિકનો ઉપયોગ કરે છે. |
કપલિંગ | ઉચ્ચ. ચાઇલ્ડ કમ્પોનન્ટ્સ તેમના પેરેન્ટના ઇમ્પ્લીમેન્ટેશન સાથે ચુસ્તપણે જોડાયેલા હોય છે. | નીચું. કમ્પોનન્ટ્સ સ્વતંત્ર છે અને ફેરફાર વિના વિવિધ સંદર્ભોમાં પુનઃઉપયોગ કરી શકાય છે. |
લવચીકતા | ઓછી. કઠોર, ક્લાસ-આધારિત હાઇરાર્કી વિવિધ કમ્પોનન્ટ ટ્રીમાં લોજિક શેર કરવાનું મુશ્કેલ બનાવે છે. | ઉચ્ચ. લોજિક અને UI ને અસંખ્ય રીતે જોડી શકાય છે અને પુનઃઉપયોગ કરી શકાય છે, જેમ કે બિલ્ડિંગ બ્લોક્સ. |
કોડની પુનઃઉપયોગીતા | પૂર્વવ્યાખ્યાયિત હાઇરાર્કી સુધી મર્યાદિત. જ્યારે તમારે ફક્ત "કેળું" જોઈતું હોય ત્યારે તમને આખો "ગોરિલો" મળે છે. | ઉત્તમ. નાના, કેન્દ્રિત કમ્પોનન્ટ્સ અને હુક્સનો સમગ્ર એપ્લિકેશનમાં ઉપયોગ કરી શકાય છે. |
રિએક્ટ ઇડિયમ | સત્તાવાર રિએક્ટ ટીમ દ્વારા નિરુત્સાહિત. | રિએક્ટ એપ્લિકેશન્સ બનાવવા માટે ભલામણ કરેલ અને ઇડિઓમેટિક અભિગમ. |
નિષ્કર્ષ: કમ્પોઝિશનની દ્રષ્ટિએ વિચારો
કમ્પોઝિશન અને ઇન્હેરિટન્સ વચ્ચેની ચર્ચા સોફ્ટવેર ડિઝાઇનમાં એક પાયાનો વિષય છે. જ્યારે ઇન્હેરિટન્સનું ક્લાસિકલ OOP માં પોતાનું સ્થાન છે, UI ડેવલપમેન્ટની ગતિશીલ, કમ્પોનન્ટ-આધારિત પ્રકૃતિ તેને રિએક્ટ માટે અયોગ્ય બનાવે છે. લાઇબ્રેરી મૂળભૂત રીતે કમ્પોઝિશનને અપનાવવા માટે ડિઝાઇન કરવામાં આવી હતી.
કમ્પોઝિશનને પસંદ કરીને, તમે મેળવો છો:
- લવચીકતા: જરૂરિયાત મુજબ UI અને લોજિકને મિશ્રિત કરવાની અને મેચ કરવાની ક્ષમતા.
- જાળવણીક્ષમતા: ઢીલી રીતે જોડાયેલા કમ્પોનન્ટ્સને સમજવા, ચકાસવા અને અલગથી રિફેક્ટર કરવા સરળ છે.
- સ્કેલેબિલિટી: કમ્પોઝિશનલ માનસિકતા નાના, પુનઃઉપયોગી કમ્પોનન્ટ્સ અને હુક્સની ડિઝાઇન સિસ્ટમ બનાવવાનું પ્રોત્સાહન આપે છે જેનો ઉપયોગ મોટી, જટિલ એપ્લિકેશન્સને અસરકારક રીતે બનાવવા માટે થઈ શકે છે.
એક વૈશ્વિક રિએક્ટ ડેવલપર તરીકે, કમ્પોઝિશનમાં નિપુણતા મેળવવી એ માત્ર શ્રેષ્ઠ પ્રથાઓનું પાલન કરવા વિશે નથી - તે મુખ્ય ફિલસૂફીને સમજવા વિશે છે જે રિએક્ટને આટલું શક્તિશાળી અને ઉત્પાદક સાધન બનાવે છે. નાના, કેન્દ્રિત કમ્પોનન્ટ્સ બનાવીને શરૂઆત કરો. સામાન્ય કન્ટેનર માટે `props.children` અને સ્પેશિયલાઇઝેશન માટે પ્રોપ્સનો ઉપયોગ કરો. લોજિક શેર કરવા માટે, પહેલા કસ્ટમ હુક્સનો ઉપયોગ કરો. કમ્પોઝિશનની દ્રષ્ટિએ વિચારીને, તમે સુંદર, મજબૂત અને સ્કેલેબલ રિએક્ટ એપ્લિકેશન્સ બનાવવાના માર્ગ પર સારી રીતે આગળ વધશો જે સમયની કસોટી પર ખરી ઉતરે.