2016-03-03 14 views
7

Il problema:ritorno elementi accoppiati in Reagire JSX

In Reagire, si vuole creare una struttura DOM mappando un array, ma ogni elemento dell'array deve restituire 2 elementi. per esempio.

import React from 'react' 
import _ from 'lodash' 

let { Component } = React 

export default class DataList extends Component { 
    render() { 
    let array = [ 
     {def: 'item1', term: 'term1', obj1: 'rand'}, 
     {def: 'item2', term: 'term2'} 
    ] 
    return (
     <dl> 
     {_.map(array, (item) => { 
      return (
      <dt>{item.def}</dt> 
      <dd>{item.term}</dd> 
     ) 
     })} 
     </dl> 
    ) 
    } 
} 

Reagire non consente il rendering fratelli senza avvolgendoli in un elemento contenitore, che possa annullare la struttura DOM qui.

risposta

10

Si potrebbe fare qualcosa di più semplice con reduce come questo:

import React, { Component } from 'react'; 

export default class DataList extends Component { 
    render() { 
    const array = [ 
     {def: 'item1', term: 'term1', obj1: 'rand'}, 
     {def: 'item2', term: 'term2'} 
    ]; 

    return (
     <dl> 
     {array.reduce((acc, item, idx) => { 
      return acc.concat([ 
       <dt key={`def-${idx}`}>{item.def}</dt>, 
       <dd key={`term-${idx}`}>{item.term}</dd> 
      ]); 
     }, [])} 
     </dl> 
    ); 
    } 
} 

DEMO :: https://jsfiddle.net/rifat/caray95v/

+2

ha, molto bello ... mi ci sono voluti alcuni secondi per capire come funzionava, che è l'unico lato negativo (cioè leggermente meno comprensibile da una leggibilità del codice POV), ma molto soluzione più elegante, e quella che userò da ora in poi. – stukennedy

+0

Un'altra cosa: in genere non è consigliabile utilizzare l'indice dell'array come chiave. Ecco un ottimo post su di esso: https://medium.com/@robinpokorny/index-as-a-key-is-an-anti-pattern-e0349aece318 – Kiril

0

Ho trovato che il modo più semplice per ottenere ciò è mappare le chiavi dell'oggetto (lodash supporta questo) per ogni elemento dell'array e rendere condizionatamente ogni tipo di elemento.

import React from 'react' 
import _ from 'lodash' 

let { Component } = React 

export default class DataList extends Component { 
    render() { 
    let array = [ 
     {def: 'item1', term: 'term1', obj1: 'rand'}, 
     {def: 'item2', term: 'term2'} 
    ] 

    return (
     <dl> 
     {_.map(array, (item) => { 
      return _.map(item, (elem, key) => { 
      if (key === 'def') { 
       return <dt>{elem}</dt> 
      } else if (key === 'term') { 
       return <dd>{elem}</dd> 
      } 
      }) 
     })} 
     </dl> 
    ) 
    } 
} 
0

Reagire 16.2 Aggiunto il supporto per Fragments, è possibile utilizzarlo in questo modo:

return (
    <dl> 
    {_.map(array, (item) => { 
     return (
     <Fragment> 
      <dt>{item.def}</dt> 
      <dd>{item.term}</dd> 
     </Fragment> 
    ) 
    })} 
    </dl> 
) 

Puoi anche usare Fragment con tag vuoto come questo:

return (
    <dl> 
    {_.map(array, (item) => { 
     return (
     <> 
      <dt>{item.def}</dt> 
      <dd>{item.term}</dd> 
     </> 
    ) 
    })} 
    </dl> 
) 

Ma tenere presente che se si desidera utilizzare l'attributo key su Fragment tag è necessario utilizzare la versione completa di esso. Maggiori informazioni su this react's blog

Problemi correlati