एक कॉम्पोनेन्ट में प्रॉप्स को भेजना

React कॉम्पोनेन्ट एक दूसरे के साथ संवाद करने के लिए प्रॉप्स का उपयोग करते हैं। प्रत्येक पैरेंट कॉम्पोनेन्ट अपने चाइल्ड कॉम्पोनेन्ट को उन्हें प्रॉप्स देकर कुछ जानकारी पास कर सकता है। प्रॉप्स आपको HTML एट्रीब्यूट्स की याद दिला सकता है, लेकिन आप इनके माध्यम से ऑब्जेक्ट्स, ऐरेज़ और फंक्शन्स सहित किसी भी JavaScript वैल्यू को पास कर सकते हैं।

You will learn

  • एक कॉम्पोनेन्ट में प्रॉप्स को कैसे पास करें
  • एक कॉम्पोनेन्ट से प्रॉप्स कैसे पढ़ें
  • प्रॉप्स के लिए डिफ़ॉल्ट वैल्यूज कैसे निर्दिष्ट करें
  • एक कॉम्पोनेन्ट में किसी JSX को कैसे पास करें
  • समय के साथ प्रॉप्स कैसे बदलते हैं

परिचित प्रॉप्स

प्रॉप्स वह जानकारी है जिसे आप एक JSX टैग में पास करते हैं। उदाहरण के लिए, className, src, alt, width, and height कुछ प्रॉप्स हैं जिन्हें आप <img> में पास कर सकते हैं:

function Avatar() {
  return (
    <img
      className="avatar"
      src="https://i.imgur.com/1bX5QH6.jpg"
      alt="Lin Lanying"
      width={100}
      height={100}
    />
  );
}

export default function Profile() {
  return (
    <Avatar />
  );
}

जो प्रॉप्स आप एक <img> टैग को पास कर सकते हैं, वे पूर्वनिर्धारित हैं (ReactDOM HTML स्टैंडर्ड के अनुरूप है।) लेकिन आप अपने स्वयं के कॉम्पोनेन्ट, जैसे <Avatar>, में उन्हें कस्टमाइज़ करने के लिए कोई भी प्रॉप्स पास कर सकते हैं। इसे ऐसे करें!

एक कॉम्पोनेन्ट में प्रॉप्स को भेजना

इस कोड में, Profile कॉम्पोनेन्ट अपने चाइल्ड कॉम्पोनेन्ट, Avatar, में कोई भी प्रॉप्स पास नहीं कर रहा है:

export default function Profile() {
return (
<Avatar />
);
}

आप Avatar को दो चरणों में कुछ प्रॉप्स दे सकते हैं।

चरण 1: चाइल्ड कॉम्पोनेन्ट को प्रॉप्स पास करें

सबसे पहले,Avatar में कुछ प्रॉप्स पास करें। उदाहरण के लिए, दो प्रॉप्स पास करें: person (एक ऑब्जेक्ट), और size (एक नंबर):

export default function Profile() {
return (
<Avatar
person={{ name: 'Lin Lanying', imageId: '1bX5QH6' }}
size={100}
/>
);
}

Note

यदि person= के बाद double curly braces आपको भ्रमित करें, याद करें के JSX curlies में वे केवल एक ऑब्जेक्ट हैं

अब आप इन प्रॉप्स को Avatar कॉम्पोनेन्ट के अंदर प्राप्त कर सकते हैं।

चरण 2: चाइल्ड कॉम्पोनेन्ट के अंदर प्रॉप्स प्राप्त करें

आप इन प्रॉप्स को उनके नाम person, size को सूचीबद्ध करके पढ़ सकते हैं, जो कि function Avatar के बाद ({ और }) के अंदर कॉमा द्वारा अलग किए गए हैं। यह आपको उन्हें Avatar के कोड के अंदर उपयोग करने देता है, जैसे आप एक वेरिएबल के साथ करेंगे।

function Avatar({ person, size }) {
// person और size यहां उपलब्ध हैं
}

Avatar में कुछ लॉजिक जोड़ें जो person और size प्रॉप्स को रेंडरिंग के लिए उपयोग करता है, और आपका कार्य पूर्ण।

अब आप विभिन्न प्रॉप्स के साथ कई अलग -अलग तरीकों से रेंडर करने के लिए Avatar को कॉन्फ़िगर कर सकते हैं। वैल्यूज में छोटे बदलाव करने का प्रयास करें!

import { getImageUrl } from './utils.js';

function Avatar({ person, size }) {
  return (
    <img
      className="avatar"
      src={getImageUrl(person)}
      alt={person.name}
      width={size}
      height={size}
    />
  );
}

export default function Profile() {
  return (
    <div>
      <Avatar
        size={100}
        person={{ 
          name: 'Katsuko Saruhashi', 
          imageId: 'YfeOqp2'
        }}
      />
      <Avatar
        size={80}
        person={{
          name: 'Aklilu Lemma', 
          imageId: 'OKS67lh'
        }}
      />
      <Avatar
        size={50}
        person={{ 
          name: 'Lin Lanying',
          imageId: '1bX5QH6'
        }}
      />
    </div>
  );
}

प्रोप्स आपको स्वतंत्र रूप से पैरेंट और चाइल्ड कॉम्पोनेंट्स के बारे में सोचने देते हैं। उदाहरण के लिए, आप Profile के अंदर person या size प्रॉप्स को बदल सकते हैं, यह सोचे बिना कि Avatar उनका उपयोग कैसे करता है। इसी प्रकार, आप बदल सकते हैं कि कैसे Avatar इन प्रॉप्स का उपयोग करता है,Profile को देखे बिना।

आप प्रॉप्स को “knobs” की तरह सोच सकते हैं जिसे आप समायोजित कर सकते हैं। वे वही भूमिका निभाते हैं जो कि फंक्शन्स के लिए आर्ग्यूमेंट्स निभाते हैं - वास्तव में, आपके कॉम्पोनेन्ट के लिए प्रॉप्स एकमात्र आर्ग्युमेंट होते हैं! React कॉम्पोनेन्ट फ़ंक्शन एक अकेला आर्ग्युमेंट, एक props ऑब्जेक्ट, स्वीकार करते हैं:

function Avatar(props) {
let person = props.person;
let size = props.size;
// ...
}

आमतौर पर आपको पूरे props ऑब्जेक्ट की आवश्यकता नहीं होती है, इसलिए आप इसे व्यक्तिगत प्रॉप्स में डीस्ट्रक्चर करते हैं।

Pitfall

प्रॉप्स को डिक्लेअर करते समय ( और ) के अंदर { और } curlies की जोड़ी को न भूलें:

function Avatar({ person, size }) {
// ...
}

इस सिंटैक्स को “destructuring” कहा जाता है और यह एक फ़ंक्शन पैरामीटर से प्रॉपर्टीज को प्राप्त करने के बराबर है:

function Avatar(props) {
let person = props.person;
let size = props.size;
// ...
}

एक प्रोप के लिए एक डिफ़ॉल्ट वैल्यू निर्दिष्ट करना

यदि आप कोई वैल्यू निर्दिष्ट न होने पर fall back के लिए एक डिफ़ॉल्ट वैल्यू देना चाहते हैं, आप इसे destructuring के द्वारा पैरामीटर के ठीक बाद = और डिफ़ॉल्ट वैल्यू डालकर कर सकते हैं:

function Avatar({ person, size = 100 }) {
// ...
}

अब, यदि <Avatar person={...} /> बिना size प्रोप के साथ रेंडर किया गया है, तो size 100 पर सेट हो जाएगा।

डिफ़ॉल्ट वैल्यू का उपयोग केवल तभी किया जाता है जब size प्रोप गायब है या यदि आप size={undefined} पास करते हैं। लेकिन अगर आप size= {null} या size={0} पास करते हैं, तो डिफ़ॉल्ट वैल्यू का उपयोग नहीं किया जाएगा।

JSX स्प्रेड सिंटैक्स का उपयोग करके प्रॉप्स को फॉरवर्ड करना

कभी-कभी, प्रॉप्स को पास करना बहुत दोहरावदार हो जाता है:

function Profile({ person, size, isSepia, thickBorder }) {
return (
<div className="card">
<Avatar
person={person}
size={size}
isSepia={isSepia}
thickBorder={thickBorder}
/>
</div>
);
}

दोहरावदार कोड के साथ कुछ भी गलत नहीं है - यह अधिक सुपाठ्य हो सकता है। लेकिन कई बार आप संक्षिप्तता को महत्व दे सकते हैं। कुछ कॉम्पोनेंट्स अपने चिल्ड्रन को अपने सभी प्रॉप्स को फॉरवर्ड कर देते हैं, जैसे कि यह Profile Avatar के साथ करता है। क्योंकि वे सीधे अपने किसी भी प्रॉप्स का उपयोग नहीं करते हैं, इसलिए यह अधिक संक्षिप्त “स्प्रेड” सिंटैक्स का उपयोग करने के लिए समझ में आ सकता है:

function Profile(props) {
return (
<div className="card">
<Avatar {...props} />
</div>
);
}

यह Profile के सभी प्रॉप्स को उनके प्रत्येक नाम को सूचीबद्ध किए बिना Avatar को फॉरवर्ड कर देता है।

स्प्रेड सिंटैक्स का उपयोग नियंत्रित रूप में करें। यदि आप इसे हर दूसरे कॉम्पोनेन्ट में उपयोग कर रहे हैं, तो कुछ गलत है। अक्सर, यह इंगित करता है कि आपको अपने कॉम्पोनेंट्स को विभाजित करना चाहिए और चिल्ड्रन को JSX के रूप में पास करना चाहिए. उस पर और अधिक आगे!

JSX को चिल्ड्रन के रूप में पास करना

built-in ब्राउज़र टैग्स को एक दूसरे के अंदर रखना (नेस्ट करना) आम बात है:

<div>
<img />
</div>

कभी-कभी आप अपने स्वयं के कॉम्पोनेंट्स को उसी तरह नेस्ट करना चाहेंगे:

<Card>
<Avatar />
</Card>

जब आप एक JSX टैग के अंदर कंटेंट को नेस्ट करते हैं, तो पैरेंट कॉम्पोनेन्ट उस कंटेंट को children नामक एक प्रोप में प्राप्त करेगा। उदाहरण के लिए, नीचे दिए गए Card कॉम्पोनेन्ट को children प्रोप प्राप्त प्राप्त होगा जो <Avatar/> पर सेट है और उसे एक wrapper div में रेंडर करेगा:

import Avatar from './Avatar.js';

function Card({ children }) {
  return (
    <div className="card">
      {children}
    </div>
  );
}

export default function Profile() {
  return (
    <Card>
      <Avatar
        size={100}
        person={{ 
          name: 'Katsuko Saruhashi',
          imageId: 'YfeOqp2'
        }}
      />
    </Card>
  );
}

<Card> के अंदर <Avatar> को कुछ टेक्स्ट के साथ बदलने का प्रयास करें, यह देखने के लिए कि Card कॉम्पोनेन्ट किसी भी नेस्टेड कंटेंट को कैसे wrap कर सकता है। इसे “जानने” की आवश्यकता नहीं है कि इसके अंदर क्या रेंडर किया जा रहा है। आप इस लचीले पैटर्न को कई स्थानों पर देखेंगे।

आप एक children प्रॉप के साथ एक कॉम्पोनेन्ट को ऐसे सोच सकते हैं, जिसमें “छेद” होता है जो कि मनमाने ढंग से JSX के साथ अपने पैरेंट कॉम्पोनेंट्स द्वारा “भरा” जा सकता है। आप अक्सर children प्रोप का visual wrappers के लिए उपयोग करेंगे: पैनल, ग्रिड, आदि।

एक पहेली जैसी कार्ड टाइल जिसमे "children" के टुकड़े जैसे text और Avatar के लिए एक स्लॉट है

Illustrated by Rachel Lee Nabors

समय के साथ प्रॉप्स कैसे बदलते हैं

नीचे दिया गया Clock कॉम्पोनेन्ट अपने पैरेंट कॉम्पोनेन्ट से दो प्रॉप्स प्राप्त करता है:ccolor और time। (पैरेंट कॉम्पोनेन्ट का कोड छोड़ दिया गया है क्योंकि यह स्टेट का उपयोग करता है, जिसमे हम अभी तक गोता नहीं लगाएंगे।)

नीचे दिए गए सेलेक्ट बॉक्स में रंग बदलने का प्रयास करें:

export default function Clock({ color, time }) {
  return (
    <h1 style={{ color: color }}>
      {time}
    </h1>
  );
}

यह उदाहरण दर्शाता है कि एक कॉम्पोनेन्ट समय के साथ अलग-अलग प्रॉप्स प्राप्त कर सकता है। प्रॉप्स हमेशा स्टैटिक नहीं होते हैं! यहाँ, time प्रोप हर सेकंड बदल रहा है, और color प्रोप तब बदलता है जब आप किसी और रंग का चयन करते हैं। प्रॉप्स केवल शुरुआत के बजाय किसी भी समय एक कॉम्पोनेन्ट के डेटा को दर्शाते हैं।

हालाँकि, प्रॉप्स अपरिवर्तनीय होते हैं - कंप्यूटर विज्ञान से शब्द “unchangeable” हैं। जब किसी कॉम्पोनेन्ट को अपने प्रॉप्स को बदलने की आवश्यकता होती है (उदाहरण के लिए, एक उपयोगकर्ता के इंटरैक्शन या नए डेटा के जवाब में), तो उसे अपने पैरेंट कॉम्पोनेन्ट को “पूछना” होगा कि वह इसे अलग प्रॉप्स- एक नई ऑब्जेक्ट पास करे! इसके पुराने प्रॉप्स को तब एक तरफ रखा जाएगा, और अंततः JavaScript इंजन उनके द्वारा ली गई मेमोरी को पुनः प्राप्त कर लेगा।

“प्रॉप्स को बदलने” की प्रयास न करें। जब आपको उपयोगकर्ता इनपुट का जवाब देने की आवश्यकता होती है (जैसे चयनित रंग को बदलना), तो आपको “स्टेट को सेट” करने की आवश्यकता होगी, जिसके बारे में आप State: एक कौम्पोनॅन्ट की मेमोरी में सीख सकते हैं।

Recap

  • प्रॉप्स पास करने के लिए, उन्हें JSX में जोड़ें, जैसे आप HTML ऐट्रिब्यूट्स के साथ करेंगे।
  • प्रॉप्स प्राप्त करने के लिए, function Avatar({ person, size }) destructuring सिंटेक्स का उपयोग करें।
  • आप डिफ़ॉल्ट वैल्यू जैसे size = 100 निर्दिष्ट कर सकते हैं, जिसका उपयोग लापता और undefined प्रॉप्स के लिए किया जाता है।
  • आप सभी प्रॉप्स को <Avatar {...props} /> JSX स्प्रेड सिंटेक्स के साथ फॉरवर्ड कर सकते हैं, लेकिन इसका अत्यधिक उपयोग न करें!
  • नेस्टेड JSX जैसे <Card><Avatar /></Card> Card कॉम्पोनेन्ट के children प्रोप के रूप में दिखाई देगा।
  • प्रॉप्स किसी विशेष समय के केवल read-only स्नैपशॉट होते हैं: प्रत्येक रेंडर प्रॉप्स का एक नया संस्करण प्राप्त करता है।
  • आप प्रॉप्स को बदल नहीं सकते। जब आपको इंटरैक्टिविटी की आवश्यकता होगी, तो आपको स्टेट सेट करनी होगी।

Challenge 1 of 3:
एक कॉम्पोनेन्ट को एक्सट्रेक्ट करें

इस Gallery कॉम्पोनेन्ट में दो प्रोफाइल के लिए कुछ समान मार्कअप है। दोहराव को कम करने के लिए इसमें से एक Profile कॉम्पोनेन्ट निकालें। आपको यह चुनना होगा कि इसमें कोनसे प्रॉप्स पास करें।

import { getImageUrl } from './utils.js';

export default function Gallery() {
  return (
    <div>
      <h1>Notable Scientists</h1>
      <section className="profile">
        <h2>Maria Skłodowska-Curie</h2>
        <img
          className="avatar"
          src={getImageUrl('szV5sdG')}
          alt="Maria Skłodowska-Curie"
          width={70}
          height={70}
        />
        <ul>
          <li>
            <b>Profession: </b> 
            physicist and chemist
          </li>
          <li>
            <b>Awards: 4 </b> 
            (Nobel Prize in Physics, Nobel Prize in Chemistry, Davy Medal, Matteucci Medal)
          </li>
          <li>
            <b>Discovered: </b>
            polonium (chemical element)
          </li>
        </ul>
      </section>
      <section className="profile">
        <h2>Katsuko Saruhashi</h2>
        <img
          className="avatar"
          src={getImageUrl('YfeOqp2')}
          alt="Katsuko Saruhashi"
          width={70}
          height={70}
        />
        <ul>
          <li>
            <b>Profession: </b> 
            geochemist
          </li>
          <li>
            <b>Awards: 2 </b> 
            (Miyake Prize for geochemistry, Tanaka Prize)
          </li>
          <li>
            <b>Discovered: </b>
            a method for measuring carbon dioxide in seawater
          </li>
        </ul>
      </section>
    </div>
  );
}