सूचियाँ प्रस्तुत करना

आप अक्सर किसी डेटा संग्रह से कई समान कंपोनेंट्स प्रदर्शित करना चाहेंगे। डेटा के array को प्रबंधित करने के लिए आप JavaScript array methods का उपयोग कर सकते हैं। इस पेज पर, आप React के साथ filter() और map() का उपयोग करेंगे ताकि अपने डेटा के array को फ़िल्टर और परिवर्तित करके कंपोनेंट्स के array में बदल सकें।

You will learn

  • JavaScript के map() का उपयोग करके array से कंपोनेंट्स को कैसे रेंडर करें।
  • JavaScript के filter() का उपयोग करके केवल विशेष कंपोनेंट्स को कैसे रेंडर करें।
  • React keys का उपयोग कब और क्यों करना चाहिए।

Arrays से डेटा रेंडर करना

मान लीजिए कि आपके पास content की एक सूची है।

<ul>
<li>Creola Katherine Johnson: mathematician</li>
<li>Mario José Molina-Pasquel Henríquez: chemist</li>
<li>Mohammad Abdus Salam: physicist</li>
<li>Percy Lavon Julian: chemist</li>
<li>Subrahmanyan Chandrasekhar: astrophysicist</li>
</ul>

उन सूची आइटम्स के बीच केवल एक अंतर होता है: उनकी contents, यानी उनका डेटा। जब आप इंटरफेस बना रहे होते हैं, तो अक्सर आपको एक ही कंपोनेंट के कई उदाहरणों को अलग-अलग डेटा के साथ दिखाने की आवश्यकता होती है, जैसे कि टिप्पणियों की सूची या प्रोफ़ाइल images की गैलरी। ऐसे मामलों में, आप उस डेटा को JavaScript ऑब्जेक्ट्स और arrays में संग्रहीत कर सकते हैं और फिर उनमें से कंपोनेंट्स की सूची रेंडर करने के लिए map() और filter() जैसे तरीकों का उपयोग कर सकते हैं।

यहां एक छोटा उदाहरण दिया गया है कि कैसे एक array से आइटम्स की सूची बनाई जा सकती है:

  1. डेटा को एक array में स्थानांतरित करें:
const people = [
'Creola Katherine Johnson: mathematician',
'Mario José Molina-Pasquel Henríquez: chemist',
'Mohammad Abdus Salam: physicist',
'Percy Lavon Julian: chemist',
'Subrahmanyan Chandrasekhar: astrophysicist'
];
  1. Map people के सदस्यों को एक नए JSX nodes के array, listItems, में परिवर्तित करें:
const listItems = people.map(person => <li>{person}</li>);
  1. Return अपने कंपोनेंट में listItems को <ul> में wrapped करें:
return <ul>{listItems}</ul>;

यहां परिणाम दिया गया है:

const people = [
  'Creola Katherine Johnson: mathematician',
  'Mario José Molina-Pasquel Henríquez: chemist',
  'Mohammad Abdus Salam: physicist',
  'Percy Lavon Julian: chemist',
  'Subrahmanyan Chandrasekhar: astrophysicist'
];

export default function List() {
  const listItems = people.map(person =>
    <li>{person}</li>
  );
  return <ul>{listItems}</ul>;
}

ध्यान दें कि ऊपर दिए गए sandbox में एक कंसोल error दिखाई दे रही है:

Console
Warning: Each child in a list should have a unique “key” prop.

आप इस error को ठीक करना बाद में सीखेंगे इस पेज पर। इससे पहले, आइए आपके डेटा को कुछ संरचना दें।

आइटम्स के arrays को फ़िल्टर करना

यह डेटा और भी अधिक structured किया जा सकता है।

const people = [{
id: 0,
name: 'Creola Katherine Johnson',
profession: 'mathematician',
}, {
id: 1,
name: 'Mario José Molina-Pasquel Henríquez',
profession: 'chemist',
}, {
id: 2,
name: 'Mohammad Abdus Salam',
profession: 'physicist',
}, {
id: 3,
name: 'Percy Lavon Julian',
profession: 'chemist',
}, {
id: 4,
name: 'Subrahmanyan Chandrasekhar',
profession: 'astrophysicist',
}];

मान लीजिए आप केवल उन लोगों को दिखाना चाहते हैं जिनका पेशा 'chemist' है। आप JavaScript के filter() method का उपयोग करके केवल उन्हीं लोगों को प्राप्त कर सकते हैं। यह method एक array को पास करता है और एक “test” (एक function जो true या false लौटाता है) के माध्यम से उन आइटम्स को फ़िल्टर करता है और केवल उन आइटम्स को एक नए array में लौटाता है जिन्होंने test पास किया (जो true लौटाते हैं)।

आप केवल उन आइटम्स को चाहते हैं जिनका profession 'chemist' है। इसके लिए “test” function इस प्रकार दिखेगा: (person) => person.profession === 'chemist'। इसे एक साथ जोड़ने का तरीका यहां है:

  1. एक नई array chemists Create करें जो केवल “chemist” वाले लोगों को दिखाती हो, filter() method का उपयोग करके person.profession === 'chemist':
const chemists = people.filter(person =>
person.profession === 'chemist'
);
  1. अब map करें chemists array पर:
const listItems = chemists.map(person =>
<li>
<img
src={getImageUrl(person)}
alt={person.name}
/>
<p>
<b>{person.name}:</b>
{' ' + person.profession + ' '}
known for {person.accomplishment}
</p>
</li>
);
  1. अब, अपने कंपोनेंट से listItems को return करें :
return <ul>{listItems}</ul>;
import { people } from './data.js';
import { getImageUrl } from './utils.js';

export default function List() {
  const chemists = people.filter(person =>
    person.profession === 'chemist'
  );
  const listItems = chemists.map(person =>
    <li>
      <img
        src={getImageUrl(person)}
        alt={person.name}
      />
      <p>
        <b>{person.name}:</b>
        {' ' + person.profession + ' '}
        known for {person.accomplishment}
      </p>
    </li>
  );
  return <ul>{listItems}</ul>;
}

Pitfall

एरो फंक्शंस स्वचालित रूप से => के बाद वाले एक्सप्रेशन को रिटर्न कर देते हैं, इसलिए आपको return स्टेटमेंट की आवश्यकता नहीं होती।

const listItems = chemists.map(person =>
<li>...</li> // Implicit return!
);

हालांकि, आपको return को स्पष्ट रूप से लिखना चाहिए यदि आपके => के बाद { कर्ली ब्रेस आ रहा है!

const listItems = chemists.map(person => { // Curly brace
return <li>...</li>;
});

एरो फंक्शंस जिनमें => { होता है, उन्हें “block body”. कहा जाता है। ये आपको एक से अधिक लाइन का कोड लिखने की अनुमति देते हैं, लेकिन आपको स्वयं return स्टेटमेंट लिखना पड़ता है। यदि आप इसे भूल जाते हैं, तो कुछ भी रिटर्न नहीं होता!

सूची आइटम्स को क्रम में रखना key

ध्यान दें कि ऊपर दिए गए सभी सैंडबॉक्स कंसोल में एक त्रुटि दिखा रहे हैं:

Console
Warning: Each child in a list should have a unique “key” prop.

आपको प्रत्येक array आइटम को एक key देना होगा — एक स्ट्रिंग या नंबर जो उसे उस array के अन्य आइटम्स में से विशिष्ट रूप से पहचान सके।

<li key={person.id}>...</li>

Note

map() कॉल के अंदर सीधे JSX elements को हमेशा keys की आवश्यकता होती है!

Keys tell React which array item each component corresponds to, so that it can match them up later. This becomes important if your array items can move (e.g. due to sorting), get inserted, or get deleted. A well-chosen key helps React infer what exactly has happened, and make the correct updates to the DOM tree.

Rather than generating keys on the fly, you should include them in your data:

Keys React को यह बताती हैं कि कौन सा array आइटम प्रत्येक कंपोनेंट से संबंधित है, ताकि React बाद में उन्हें मेल कर सके। यह महत्वपूर्ण हो जाता है यदि आपके array आइटम्स को स्थानांतरित (जैसे कि सॉर्टिंग के कारण), जोड़ा, या हटाया जा सकता है। एक अच्छे तरीके से चुनी गई key React को यह अनुमान लगाने में मदद करती है कि क्या हुआ है, और DOM वृक्ष में सही अपडेट्स कराती है।

key को तुरंत जनरेट करने के बजाय, आपको उन्हें अपने डेटा में शामिल करना चाहिए।

export const people = [{
  id: 0, // Used in JSX as a key
  name: 'Creola Katherine Johnson',
  profession: 'mathematician',
  accomplishment: 'spaceflight calculations',
  imageId: 'MK3eW3A'
}, {
  id: 1, // Used in JSX as a key
  name: 'Mario José Molina-Pasquel Henríquez',
  profession: 'chemist',
  accomplishment: 'discovery of Arctic ozone hole',
  imageId: 'mynHUSa'
}, {
  id: 2, // Used in JSX as a key
  name: 'Mohammad Abdus Salam',
  profession: 'physicist',
  accomplishment: 'electromagnetism theory',
  imageId: 'bE7W1ji'
}, {
  id: 3, // Used in JSX as a key
  name: 'Percy Lavon Julian',
  profession: 'chemist',
  accomplishment: 'pioneering cortisone drugs, steroids and birth control pills',
  imageId: 'IOjWm71'
}, {
  id: 4, // Used in JSX as a key
  name: 'Subrahmanyan Chandrasekhar',
  profession: 'astrophysicist',
  accomplishment: 'white dwarf star mass calculations',
  imageId: 'lrWQx8l'
}];

Deep Dive

प्रत्येक सूची आइटम के लिए कई DOM नोड्स को प्रदर्शित करना

जब प्रत्येक आइटम को केवल एक नहीं, बल्कि कई DOM नोड्स रेंडर करने की आवश्यकता हो, तो आप क्या करेंगे?

The short <>...</> Fragment syntax won’t let you pass a key, so you need to either group them into a single <div>, or use the slightly longer and more explicit <Fragment> syntax: संक्षिप्त <>...</> फ्रैगमेंट सिंटैक्स आपको एक key पास करने की अनुमति नहीं देता, इसलिए आपको या तो उन्हें एकल <div> में समूहित करना होगा, या थोड़ा लंबा और अधिक स्पष्ट <Fragment> सिंटैक्स का उपयोग करना होगा।

import { Fragment } from 'react';

// ...

const listItems = people.map(person =>
<Fragment key={person.id}>
<h1>{person.name}</h1>
<p>{person.bio}</p>
</Fragment>
);

फ्रैगमेंट्स DOM से गायब हो जाते हैं, इसलिए यह <h1>, <p>, <h1>, <p>, और इस तरह की एक सपाट सूची उत्पन्न करेगा।

अपना key कहां से प्राप्त करें

डेटा के विभिन्न स्रोत विभिन्न प्रकार की keys प्रदान करते हैं:

  • डेटा डेटाबेस से: यदि आपका डेटा डेटाबेस से आ रहा है, तो आप डेटाबेस keys/IDs का उपयोग कर सकते हैं, जो स्वभाव से अद्वितीय होती हैं।

  • स्थानीय रूप से उत्पन्न डेटा: यदि आपका डेटा स्थानीय रूप से उत्पन्न और संग्रहित किया गया है (जैसे कि नोट-लेने वाले ऐप में नोट्स), तो आइटम बनाते समय एक बढ़ता हुआ काउंटर, crypto.randomUUID() या uuid जैसे पैकेज का उपयोग करें।

keys के नियम

  • keys को सिबलिंग्स के बीच अद्वितीय होना चाहिए। हालांकि, विभिन्न arrays में JSX नोड्स के लिए एक ही keys का उपयोग करना ठीक है।
  • keys को बदलना नहीं चाहिए वरना उनका उद्देश्य ही समाप्त हो जाएगा! उन्हें रेंडर करते समय उत्पन्न न करें।

React को keys की आवश्यकता क्यों है?

कल्पना करें कि आपके डेस्कटॉप पर फाइलों के नाम नहीं होते। इसके बजाय, आप उन्हें उनके क्रम के अनुसार संदर्भित करते — पहली फाइल, दूसरी फाइल, और इसी तरह। आप इसके आदी हो सकते थे, लेकिन जैसे ही आप एक फाइल को डिलीट करते, यह उलझन में डाल सकता था। दूसरी फाइल पहली फाइल बन जाती, तीसरी फाइल दूसरी फाइल बन जाती, और इसी तरह।

एक फोल्डर में फाइल नाम और array में JSX keys का उद्देश्य समान होता है। ये हमें एक आइटम को उसके सिबलिंग्स के बीच अद्वितीय रूप से पहचानने की अनुमति देते हैं। एक अच्छे तरीके से चुनी गई key अधिक जानकारी देती है, न केवल array में स्थिति के बारे में। यहां तक कि यदि स्थिति पुनर्व्यवस्थित होने के कारण बदलती है, तो key React को आइटम को उसकी पूरी जीवनकाल के दौरान पहचानने में मदद करती है।

Pitfall

आपको किसी आइटम के इंडेक्स को उसकी key के रूप में उपयोग करने का मन हो सकता है। दरअसल, यही React उपयोग करेगा यदि आप key को बिल्कुल निर्दिष्ट नहीं करते। लेकिन यदि कोई आइटम डाली जाती है, डिलीट होती है, या यदि array का पुनर्व्यवस्थापन होता है, तो आपके द्वारा रेंडर किए गए आइटम्स का क्रम समय के साथ बदल जाएगा। इंडेक्स को key के रूप में उपयोग करना अक्सर सूक्ष्म और उलझन भरे बग्स का कारण बनता है।

इसी तरह, तुरंत कीज़ उत्पन्न न करें, जैसे कि key={Math.random()} के साथ। इससे keys रेंडर के बीच कभी मेल नहीं खाएंगी, जिससे हर बार आपके सभी कंपोनेंट्स और DOM को फिर से बनाना पड़ेगा। यह न केवल धीमा है, बल्कि यह सूची आइटम्स के अंदर किसी भी उपयोगकर्ता इनपुट को भी खो देगा। इसके बजाय, डेटा पर आधारित एक स्थिर ID का उपयोग करें।

ध्यान दें कि आपके कंपोनेंट्स को key प्रॉप के रूप में प्राप्त नहीं होगी। इसे केवल React खुद द्वारा एक संकेत के रूप में उपयोग किया जाता है। यदि आपके कंपोनेंट को ID की आवश्यकता है, तो आपको इसे एक अलग प्रॉप के रूप में पास करना होगा: <Profile key={id} userId={id} />

Recap

इस पृष्ठ पर आपने सीखा:

  • कैसे डेटा को कंपोनेंट्स से बाहर ले जाकर डेटा संरचनाओं जैसे arrays और ऑब्जेक्ट्स में रखा जाए।
  • कैसे JavaScript के map() का उपयोग करके समान कंपोनेंट्स के सेट बनाए जाएं।
  • कैसे JavaScript के filter() का उपयोग करके फ़िल्टर किए गए आइटम्स के arrays बनाए जाएं।
  • क्यों और कैसे प्रत्येक कंपोनेंट पर key सेट किया जाए ताकि React उन्हें ट्रैक कर सके, भले ही उनकी स्थिति या डेटा बदल जाए।

Challenge 1 of 4:
एक सूची को दो में विभाजित करना

यह उदाहरण सभी लोगों की एक सूची दिखाता है।

इसे दो अलग-अलग सूचियाँ एक के बाद एक दिखाने के लिए बदलें: Chemists और बाकी सभी। जैसा कि पहले था, आप यह निर्धारित कर सकते हैं कि कोई व्यक्ति केमिस्ट है या नहीं, इसके लिए आप person.profession === 'chemist' की जांच कर सकते हैं।

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

export default function List() {
  const listItems = people.map(person =>
    <li key={person.id}>
      <img
        src={getImageUrl(person)}
        alt={person.name}
      />
      <p>
        <b>{person.name}:</b>
        {' ' + person.profession + ' '}
        known for {person.accomplishment}
      </p>
    </li>
  );
  return (
    <article>
      <h1>Scientists</h1>
      <ul>{listItems}</ul>
    </article>
  );
}