मानचित्र का उपयोग करके प्रतिक्रिया घटकों को कैसे प्रस्तुत करें और शामिल हों


102

मेरे पास एक घटक है जो Arring of String प्रदर्शित करने जा रहा है। कोड इस तरह दिखता है।

React.createClass({
  render() {
     <div>
        this.props.data.map(t => <span>t</span>)
     </div>
  }
})

यह पूरी तरह से ठीक काम कर रहा है। अर्थात यदि props.data = ['tom', 'jason', 'chris'] पृष्ठ में प्रदान किया गया परिणाम tomjasonchris होगा

फिर, मैं कॉमा का उपयोग करके सभी नामों में शामिल होना चाहता हूं, इसलिए मैं कोड को बदल देता हूं

this.props.data.map(t => <span>t</span>).join(', ')

हालांकि, प्रदान किया गया परिणाम [वस्तु], [वस्तु], [वस्तु] है।

मुझे नहीं पता कि वस्तु की व्याख्या कैसे की जाए ताकि प्रतिक्रिया करने वाले घटक बन सकें। कोई उपाय ?

जवाबों:


150

एक सरल समाधान reduce()दूसरे तर्क के बिना और पिछले परिणाम को फैलाने के बिना उपयोग करना है :

class List extends React.Component {
  render() {
     <div>
        {this.props.data
          .map(t => <span>{t}</span>)
          .reduce((prev, curr) => [prev, ', ', curr])}
     </div>
  }
}

दूसरे तर्क के बिना, सूचकांक 1 पर शुरूreduce() होगा 0 के बजाय , और रिएक्टेड नेस्टेड सरणियों से पूरी तरह से खुश है।

जैसा कि टिप्पणियों में कहा गया है, आप केवल कम से कम एक आइटम के साथ सरणियों के लिए इसका उपयोग करना चाहते हैं, क्योंकि reduce() बिना दूसरे तर्क के खाली सरणी के साथ फेंक देंगे। आम तौर पर यह एक समस्या नहीं होनी चाहिए, क्योंकि आप किसी कस्टम संदेश को प्रदर्शित करना चाहते हैं, जैसे किसी भी तरह खाली सरणियों के लिए 'यह खाली है'।

टाइपस्क्रिप्ट के लिए अद्यतन

आप इसे टाइपस्क्रिप्ट (टाइप-असुरक्षित के बिना any) पर एक React.ReactNodeप्रकार के पैरामीटर के साथ उपयोग कर सकते हैं .map():

class List extends React.Component {
  render() {
     <div>
        {this.props.data
          .map<React.ReactNode>(t => <span>{t}</span>)
          .reduce((prev, curr) => [prev, ', ', curr])}
     </div>
  }
}

3
If the array is empty and no initialValue was provided, TypeError would be thrown.। इसलिए यह खाली सरणी के लिए काम नहीं करेगा।
यूजीन क्रेवनेट्स 17:29 बजे

6
यह भी ध्यान दें कि यह पुनरावर्ती prevसरणी को घोंसला बनाता है । जैसे [1, 2, 3, 4]बन जाता है [[[1,",",2],",",3],",",4]
टामलिन

2
@Tamlyn: क्या आपको लगता है कि उत्तर में आपकी बात का मेरा मूल उल्लेख ('प्रतिक्रिया पूरी तरह से नेस्टेड सरणियों से खुश है') पर्याप्त स्पष्ट है या मुझे इस पर विस्तार से बताना चाहिए?
मार्टन टेर हॉर्स्ट

1
किसी ने इस समाधान को प्रतिक्रिया + टाइपस्क्रिप्ट के साथ काम किया?
मैट डेल

1
@ Jstuff मैं किसी भी का उपयोग करने के लिए eneded। .reduce((prev: JSX.Element, current: JSX.Element): any => [prev, (<span>&nbsp;</span>), current])
मैट डेल

26

आप reduceकिसी सरणी के कई तत्वों को संयोजित करने के लिए उपयोग कर सकते हैं :

React.createClass({
  render() {
     <div>
        this.props.data
        .map(t => <span>t</span>)
        .reduce((accu, elem) => {
            return accu === null ? [elem] : [...accu, ',', elem]
        }, null)
     </div>
  }
})

यह संचयकर्ता को शून्य से आरंभ करता है, इसलिए हम पहले आइटम को एक सरणी में लपेट सकते हैं। सरणी में प्रत्येक निम्न तत्व के लिए, हम एक नए सरणी का निर्माण करते हैं जिसमें सभी पिछले तत्वों का उपयोग होता है...-operator , विभाजक और फिर अगला तत्व जोड़ें।

Array.prototype.reduce ()


2
धन्यवाद, वास्तव में मुझे क्या चाहिए। आप संचयकर्ता को एक खाली सरणी के रूप में प्रारंभ करके अशक्त चेक और टर्नरी को निकाल सकते हैं
लैरी

7
@Larry यदि आप अशक्त चेक और टर्नरी को हटाते हैं, और आरम्भक के रूप में पास करते हैं, तो आप एक अग्रणी अल्पविराम से कैसे बचते हैं? ['a'].reduce((a, e) => [...a, ',', e],[])पैदावार [",", "a"]। जब तक सरणी खाली नहीं होती है, तब तक कोई आरंभिक पासिंग काम नहीं करता है, इस स्थिति में यह टाइपएयर्रर देता है।
गाइ

@ जीयूयू आप बिल्कुल सही हैं - मेरी त्रुटि यह थी कि मैं रिक्त स्थान के साथ मूल्यों में शामिल हो रहा था, और प्रदान किए गए आउटपुट में खाली अवधि को याद कर रहा था
लैरी

12

प्रतिक्रिया 16 के साथ अपडेट करें: अब स्ट्रिंग्स को सीधे रेंडर करना संभव है, इसलिए आप सभी बेकार <span>टैग को हटाकर अपने कोड को सरल बना सकते हैं ।

const list = ({ data }) => data.reduce((prev, curr) => [ prev, ', ', curr ]);

8

स्वीकृत उत्तर वास्तव में सरणियों का एक सरणी देता है क्योंकि prev हर बार एक सरणी होगी। इस कार्य को करने के लिए रिएक्ट काफी स्मार्ट है, लेकिन क्या यह भविष्य में समस्या पैदा करने के लिए प्रवण है जैसे कि मैप के प्रत्येक परिणाम के लिए कुंजी देते समय रिएक्ट को अलग करना एल्गोरिथ्म को तोड़ना।

नई React.Fragmentसुविधा हमें अंतर्निहित मुद्दों के बिना आसान तरीके से समझने में मदद करती है।

class List extends React.Component {
  render() {
     <div>
        {this.props.data
          .map((t, index) => 
            <React.Fragment key={index}>
              <span> {t}</span> ,
            </React.Fragment>
          )
      </div>
  }
}

साथ React.Fragmentहम बस विभाजक जगह कर सकते हैं ,वापस आ HTML के के बाहर और प्रतिक्रिया शिकायत नहीं होंगे।


2
बहुत बढ़िया समाधान है, लेकिन आपको सरणी के अंतिम तत्व के लिए अल्पविराम को हटाने की आवश्यकता है
indapublic

आप इसे हल करने के लिए हमेशा एक टर्नरी और इंडेक्स का उपयोग कर सकते हैं।
जस्तफ

2
आप इस संशोधन के साथ अंतिम अल्पविराम को हटा सकते हैं: <React.Fragment कुंजी = {index}> <span> {t} </ span> {index === this.props.data.length - 1? '': ','} </React.Fragment>
JohnP

7

<span>{t}</span>आप लौट रहे एक वस्तु, न कोई स्ट्रिंग है। इसके बारे में प्रतिक्रिया डॉक्स की जाँच करें https://facebook.github.io/react/docs/jsx-in-depth.html#the-transform

से .join()लौटे सरणी पर उपयोग करके map, आप ऑब्जेक्ट की सरणी में शामिल हो रहे हैं।[object Object], ...

आप कॉमा को अंदर रख सकते हैं <span></span>ताकि यह जिस तरह से आप इसे चाहते हैं, इसका प्रतिपादन किया जा सके।

  render() {
    return (
      <div>
        { this.props.data.map(
            (t,i) => <span>{t}{ this.props.data.length - 1 === i ? '' : ','} </span>
          )
        }
      </div>
    )
  }

नमूना: https://jsbin.com/xomopahalo/edit?html,js,output


3

मेरा संस्करण:

{this.props.data
    .map(item => <span>{item}</span>)
    .map((item, index) => [index > 0 && ', ', item ])}

2

अगर मैं घटकों के अल्पविराम से अलग किए गए सरणी को प्रस्तुत करना चाहता हूं, तो मुझे आमतौर पर reduceबहुत अधिक क्रिया मिलती है। ऐसे मामलों में एक छोटा समाधान है

{arr.map((item, index) => (
  <Fragment key={item.id}>
    {index > 0 && ', '}
    <Item {...item} />
  </Fragment>
))}

{index > 0 && ', '} पहले वाले को छोड़कर सभी सरणी वस्तुओं के सामने एक स्थान के बाद अल्पविराम प्रदान करेगा।

आप दूसरे करने के लिए पिछले आइटम और कुछ और के द्वारा पिछले एक अलग करने के लिए चाहते हैं, कहते हैं कि स्ट्रिंग ' and ', आप बदल सकते हैं {index > 0 && ', '}साथ

{index > 0 && index !== arr.length - 1 && ', '}
{index === arr.length - 1 && ' and '}

2

Es6 के उपयोग से आप कुछ ऐसा कर सकते हैं:

const joinComponents = (accumulator, current) => [
  ...accumulator, 
  accumulator.length ? ', ' : '', 
  current
]

और फिर चलाएं:

listComponents
  .map(item => <span key={item.id}> {item.t} </span>)
  .reduce(joinComponents, [])

1

"," बाहर रखने के लिए नेस्टेड सरणी का उपयोग करें।

  <div>
      {this.props.data.map((element, index) => index == this.props.data.length - 1 ? <span key={index}>{element}</span> : [<span key={index}>{element}</span>, ", "])}
  </div>

डेटा को सहेजकर इसे ऑप्टिमाइज़ करें और जाँचें कि अंतिम तत्व को संशोधित करने के बजाय यदि इसका अंतिम तत्व हर समय है।

  let processedData = this.props.data.map((element, index) => [<span key={index}>{element}</span>, ", "])
  processedData [this.props.data.length - 1].pop()
  <div>
      {processedData}
  </div>

0

यह मेरे लिए काम किया:

    {data.map( ( item, i ) => {
                  return (
                      <span key={i}>{item.propery}</span>
                    )
                  } ).reduce( ( prev, curr ) => [ prev, ', ', curr ] )}

0

जैसा कि पिथ द्वारा उल्लेख किया गया है , प्रतिक्रिया 16 आपको स्ट्रिंग्स का उपयोग करने की अनुमति देता है ताकि स्पैन टैग में स्ट्रिंग्स को लपेटने की अब आवश्यकता नहीं है। मैर्टन के उत्तर पर निर्माण , यदि आप तुरंत एक कस्टम संदेश से निपटना चाहते हैं (और खाली सरणी पर एक त्रुटि को फेंकने से बचें), तो आप सरणी पर लंबाई संपत्ति पर बयान के साथ ऑपरेशन का नेतृत्व कर सकते हैं। जो कुछ इस तरह दिख सकता है:

class List extends React.Component {
  const { data } = this.props;

  render() {
     <div>
        {data.length
          ? data.reduce((prev, curr) => [prev, ', ', curr])
          : 'No data in the array'
        }
     </div>
  }
}

0

यह एक फ्लैट सरणी वापस करना चाहिए। एक प्रारंभिक खाली सरणी प्रदान करके गैर-चलने योग्य पहली वस्तु के साथ मामला संभालें और परिणाम से पहले अल्पविराम की आवश्यकता को फ़िल्टर नहीं करें

[{}, 'b', 'c'].reduce((prev, curr) => [...prev, ', ', curr], []).splice(1) // => [{}, 'b', 'c']

0

क्या मैं अकेला हूँ जो सोचता है कि यहाँ उत्तरों में बहुत सारे अनावश्यक फैलाव और घोंसले बन रहे हैं? संक्षिप्त होने के लिए अंक, निश्चित रूप से, लेकिन यह स्केल या रिएक्ट के मुद्दों के लिए दरवाजा खुला छोड़ देता है कि वे कैसे नेस्टेड सरणियों / फ्रैगमेंट से निपटते हैं।

const joinJsxArray = (arr, joinWith) => {
  if (!arr || arr.length < 2) { return arr; }

  const out = [arr[0]];
  for (let i = 1; i < arr.length; i += 1) {
    out.push(joinWith, arr[i]);
  }
  return out;
};

// render()
<div>
  {joinJsxArray(this.props.data.map(t => <span>t</span>), ', ')}
</div>

एक सरणी, कोई घोंसला नहीं। या तो कोई सेक्सी विधि नहीं है, लेकिन अगर आप अपने आप को ऐसा करते हुए पाते हैं, तो आप इसे हमेशा ऐरे प्रोटोटाइप में जोड़ सकते हैं या इसे किसी ऐसे फंक्शन में लपेट सकते हैं, जिसमें मैपिंग कॉलबैक के साथ-साथ यह सब एक बार में किया जा सके।


0
function YourComponent(props) {

  const criteria = [];

  if (something) {
    criteria.push(<strong>{ something }</strong>);
  }

  // join the jsx elements with `, `
  const elements = criteria.reduce((accu, elem) => {
    return accu === null ? [elem] : [...accu, ', ', elem]
  }, null);

  // render in a jsx friendly way
  return elements.map((el, index) => <React.Fragment key={ index }>{ el }</React.Fragment> );

}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.