Come evitare il wrapping aggiuntivo <div> in React?


114

Oggi ho iniziato ad imparare ReactJS e dopo un'ora ho affrontato il problema .. Voglio inserire un componente che ha due righe all'interno di un div sulla pagina. Un esempio semplificato di quello che sto facendo di seguito.

Ho un html:

<html>
..
  <div id="component-placeholder"></div>
..
</html>

Funzione di rendering in questo modo:

...
render: function() {

    return(
        <div className="DeadSimpleComponent">
            <div className="DeadSimpleComponent__time">10:23:12</div >
            <div className="DeadSimpleComponent__date">MONDAY, 2 MARCH 2015</div>
        </div>
    )
}
....

E di seguito chiamo render:

ReactDOM.render(<DeadSimpleComponent/>, document.getElementById('component-placeholder'));

L'HTML generato ha questo aspetto:

<html>
..
  <div id="component-placeholder">
    <div class="DeadSimpleComponent">
            <div class="DeadSimpleComponent__time">10:23:12</div>
            <div class="DeadSimpleComponent__date">MONDAY, 2 MARCH 2015</div>
    </div>
</div>
..
</html>

Il problema che non sono molto contento è che React mi costringe a racchiudere tutto in un div "DeadSimpleComponent". Qual è la soluzione migliore e semplice per questo, senza manipolazioni DOM esplicite?

AGGIORNAMENTO 28/07/2017: I manutentori di React hanno aggiunto questa possibilità in React 16 Beta 1

A partire da React 16.2 , puoi farlo:

render() {
  return (
    <>
      <ChildA />
      <ChildB />
      <ChildC />
    </>
  );
}

4
perfetta pratica di denominazione ;-)
Kirill Reznikov

Posso vedere il tuo file HTML? Ho letto male la tua domanda. Tuttavia, potrei avere una soluzione alternativa.
Louis93


Hai un problema con un componente che ha un singolo elemento? Veramente?
Dominic

Cosa intendi? Sto solo provando React, non dovrebbe essere molto complicato .. Ma la limitazione sembra fastidiosa.
Kirill Reznikov

Risposte:


142

Questo requisito è stato rimosso nella versione React (16.0)] 1 , quindi ora puoi evitare quel wrapper.

Puoi usare React.Fragment per rendere un elenco di elementi senza creare un nodo padre, esempio ufficiale:

render() {
  return (
    <React.Fragment>
      <ChildA />
      <ChildB />
      <ChildC />
    </React.Fragment>
  );
}

Maggiori informazioni qui: Frammenti


1
Grandi notizie DmitryUlyanets. È prevista una data di rilascio?
Jonas Carlbaum

È stato rilasciato dal 26 settembre 2017, vedi reactjs.org/blog/2017/09/26/react-v16.0.html
Tom

56

Aggiornamento 2017-12-05: React v16.2.0 ora supporta completamente il rendering dei frammenti con un supporto migliorato per la restituzione di più figli da un metodo di rendering dei componenti senza specificare le chiavi nei figli:

render() {
  return (
    <>
      <ChildA />
      <ChildB />
      <ChildC />
    </>
  );
}

Se stai usando una versione di React precedente alla v16.2.0, è anche possibile usare <React.Fragment>...</React.Fragment>invece:

render() {
  return (
    <React.Fragment>
      <ChildA />
      <ChildB />
      <ChildC />
    </React.Fragment>
  );
}

Originale:

React v16.0 ha introdotto la restituzione di un array di elementi nel metodo render senza avvolgerlo in un div: https://reactjs.org/blog/2017/09/26/react-v16.0.html

render() {
  // No need to wrap list items in an extra element!
  return [
    // Don't forget the keys :)
    <li key="A">First item</li>,
    <li key="B">Second item</li>,
    <li key="C">Third item</li>,
  ];
}

Al momento, è necessaria una chiave per ogni elemento per evitare l'avvertimento della chiave, ma questo potrebbe essere modificato nelle versioni future:

In futuro, probabilmente aggiungeremo una sintassi di frammento speciale a JSX che non richiede chiavi.


La nuova sintassi abbreviata di <> </> è fantastica. Tuttavia, ho ancora sentimenti contrastanti al riguardo.
Thulani Chivandikwa

@ThulaniChivandikwa Ti dispiacerebbe esprimere i tuoi dubbi sulla sintassi abbreviata?
Tom il

1
Penso che riguardi più il concetto di un tag vuoto che è strano nel JSX e non molto intuitivo a meno che tu non sappia esattamente cosa fa.
Thulani Chivandikwa


3

Usa [], invece di () per racchiudere l'intero ritorno.

render: function() {
  return[
    <div className="DeadSimpleComponent__time">10:23:12</div >
    <div className="DeadSimpleComponent__date">MONDAY, 2 MARCH 2015</div>
  ]
}


1

Questo è ancora necessario , MA React ora assicurati di creare elementi senza creare un elemento DOM aggiuntivo.

Il wrapping extra necessario (normalmente con un genitore div) perché il createElementmetodo Reacts richiede un typeparametro che è either a tag name string (such as 'div' or 'span'), a React component type (a class or a function). Ma questo è stato prima che introducessero React Fragment.

Fare riferimento a questo NUOVO documento api per createElement

React.createElement : crea e restituisce un nuovo elemento React del tipo specificato. L'argomento del tipo può essere una stringa del nome del tag (come "div" o "span"), un tipo di componente React (una classe o una funzione) o un tipo di frammento React .

ecco l'esempio ufficiale, Refer React.Fragment .

render() {
  return (
    <React.Fragment>
      Some text.
      <h2>A heading</h2>
    </React.Fragment>
  );
}

0

Non sarai in grado di sbarazzarti di divquell'elemento. React.render () deve restituire un nodo DOM valido.


i div vengono ignorati, Knockout.JS fa la stessa cosa. avere un div senza styling sulla parte esterna del tuo componente non ha alcun effetto.
Chris Hawkes

16
@ChrisHawkes, non sono d'accordo. un div wrapper influenza i selettori CSS.
Downhillski

Quando lavori con elementi semantici, che non vuoi essere interamente componenti React, questo diventa un problema. Diciamo che c'è un tag di sezione con elementi di intestazione e piè di pagina, e tra di essi c'è un contenitore di mappa di Google, che non vogliamo usare in React. Quindi sarebbe bello avere un'intestazione come componente React e un piè di pagina come componente React, senza dover includere div extra all'esterno all'interno dei componenti React ... Questo è un design semplicemente stupido, se ti interessa affatto l'html si
esce

0

Ecco un modo per rendere i componenti "transculenti":

import React from 'react'

const Show = (props) => {
  if (props.if || false) {
    return (<React.Fragment>{props.children}</React.Fragment>)
  }
  return '';
};

----


<Show if={yomama.so.biq}>
    <img src="https://yomama.so.biq">
    <h3>Yoamama</h3>
<Show>

inserisci qui la descrizione dell'immagine


0

C'è anche una soluzione alternativa. Il codice di blocco sottostante genera frammento senza la necessità di React.Fragment.

return [1,2,3].map(i=>{
if(i===1) return <div key={i}>First item</div>
if(i===2) return <div key={i}>Second item</div>
return <div key={i}>Third item</div>
})

0

So che questa domanda ha avuto risposta, ovviamente puoi usare React.Fragment che non crea un nodo ma ti consente di raggruppare cose come un div.

Inoltre, se vuoi divertirti, puoi implementare (e imparare un sacco di cose) una modalità React che rimuove i div extra e per questo voglio davvero condividere un ottimo video su come puoi farlo sulla base del codice reattivo stesso.

https://www.youtube.com/watch?v=aS41Y_eyNrU

Questo ovviamente non è qualcosa che faresti in pratica, ma è una buona opportunità di apprendimento.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.