Mostra o nascondi elemento in React

Sto scherzando con React.js per la prima volta e non riesco a trovare un modo per mostrare o hide qualcosa su una pagina tramite l’evento click. Non sto caricando altre librerie sulla pagina, quindi sto cercando un modo nativo usando la libreria React. Questo è quello che ho finora. Vorrei mostrare i risultati div quando scatta l’evento click.

var Search= React.createClass({ handleClick: function (event) { console.log(this.prop); }, render: function () { return ( 
); } }); var Results = React.createClass({ render: function () { return (
Some Results
); } }); React.renderComponent( , document.body);

La chiave è aggiornare lo stato del componente nel gestore di clic utilizzando setState . Quando vengono applicate le modifiche dello stato, il metodo di render viene richiamato di nuovo con il nuovo stato:

 var Search = React.createClass({ getInitialState: function() { return { showResults: false }; }, onClick: function() { this.setState({ showResults: true }); }, render: function() { return ( 
{ this.state.showResults ? : null }
); } }); var Results = React.createClass({ render: function() { return (
Some Results
); } }); ReactDOM.render(, document.getElementById('container'));

http://jsfiddle.net/kb3gN/15084/

  
 render: function() { return ( 
This will be hidden if you set props.shouldHide to something truthy.
); }

Ecco una syntax alternativa per l’operatore ternario:

 { this.state.showMyComponent ?  : null } 

è equivalente a:

 { this.state.showMyComponent &&  } 

Magra perché


Anche syntax alternativa con display: 'none';

  

Tuttavia, se si abusa il display: 'none' , questo porta all’inquinamento DOM e alla fine rallenta l’applicazione.

Ecco il mio approccio usando ES6. Mentre la risposta accettata è corretta, è abbastanza obsoleta.

 import React, { Component } from 'react'; // you should use ReactDOM.render instad of React.renderComponent import ReactDOM from 'react-dom'; class ToggleBox extends Component { constructor(props) { super(props); this.state = { // toggle box is closed initially isOpened: false, }; // http://egorsmirnov.me/2015/08/16/react-and-es6-part3.html this.toggleBox = this.toggleBox.bind(this); } toggleBox() { // check if box is currently opened const { isOpened } = this.state; this.setState({ // toggle value of `opened` isOpened: !opened, }); } render() { const { title, children } = this.props; const { isOpened } = this.state; return ( 
{title}
{isOpened && children && (
{children}
)}
); } } ReactDOM.render((
Some content
), document.getElementById('app'));

Demo: http://jsfiddle.net/kb3gN/16688/

È meglio rendere qualche elemento solo se necessario piuttosto che aggiungere alcune classi css con display: none . Se imposti display: none – l’elemento è ancora visualizzato reagendo e aggiunto al DOM – che può avere un impatto negativo sulle prestazioni.

Immagina di avere una pagina con le tabs, in cui ogni scheda contiene molti contenuti e in cui viene aperta solo una scheda in una sola volta. È molto meglio mantenere nel DOM solo quegli elementi che dovrebbero essere visualizzati.

Nel codice sopra, per ottenere questo, sto usando il codice come:

 {opened && } 

Ciò renderà SomeElement solo se opened è vero. Funziona a causa del modo in cui JavaScript risolve le condizioni logiche:

 true && true && 2; // will output 2 true && false && 2; // will output false true && 'some string'; // will output 'some string' opened && ; // will output SomeElement if `opened` is true, will output false otherwise 

con la versione più recente reagisci 0.11 puoi anche solo restituire null per non avere alcun contenuto reso.

https://facebook.github.io/react/blog/2014/07/13/react-v0.11-rc1.html#rendering-to-null

Ho creato un piccolo componente che gestisce questo per te: https://www.npmjs.com/package/react-toggle-display

Imposta l’attributo di stile da display: none !important basato sul hide o show oggetti di scena.

Esempio di utilizzo:

 var ToggleDisplay = require('react-toggle-display'); var Search = React.createClass({ getInitialState: function() { return { showResults: false }; }, onClick: function() { this.setState({ showResults: true }); }, render: function() { return ( 
); } }); var Results = React.createClass({ render: function() { return (
Some Results
); } }); React.renderComponent(, document.body);

Si imposta un valore booleano nello stato (ad es. “Mostra”), quindi si esegue:

 var style = {}; if (!this.state.show) { style.display = 'none' } return 
...

Ci sono già molte ottime risposte, ma non penso che siano state spiegate molto bene e molti dei metodi forniti contengono alcuni trucchi che potrebbero far inciampare la gente. Quindi ho intenzione di andare oltre i tre modi principali (più un’opzione off-topic) per fare questo e spiegare i pro ei contro. Scrivo principalmente questo perché l’opzione 1 è stata consigliata molto e ci sono molti potenziali problemi con questa opzione se non utilizzati correttamente.

Opzione 1: Rendering condizionale nel genitore.

Non mi piace questo metodo a meno che tu non abbia intenzione di renderizzare il componente una sola volta e lasciarlo lì. Il problema è che causerà reactjs per creare il componente da zero ogni volta che si triggers la visibilità. Ecco l’esempio. LogoutButton o LoginButton vengono resi condizionalmente nel LoginControl principale. Se lo esegui, noterai che il costruttore viene chiamato per ogni clic del pulsante. https://codepen.io/Kelnor/pen/LzPdpN?editors=1111

 class LoginControl extends React.Component { constructor(props) { super(props); this.handleLoginClick = this.handleLoginClick.bind(this); this.handleLogoutClick = this.handleLogoutClick.bind(this); this.state = {isLoggedIn: false}; } handleLoginClick() { this.setState({isLoggedIn: true}); } handleLogoutClick() { this.setState({isLoggedIn: false}); } render() { const isLoggedIn = this.state.isLoggedIn; let button = null; if (isLoggedIn) { button = ; } else { button = ; } return ( 
{button}
); } } class LogoutButton extends React.Component{ constructor(props, context){ super(props, context) console.log('created logout button'); } render(){ return ( ); } } class LoginButton extends React.Component{ constructor(props, context){ super(props, context) console.log('created login button'); } render(){ return ( ); } } function UserGreeting(props) { return

Welcome back!

; } function GuestGreeting(props) { return

Please sign up.

; } function Greeting(props) { const isLoggedIn = props.isLoggedIn; if (isLoggedIn) { return ; } return ; } ReactDOM.render( , document.getElementById('root') );

Ora React è abbastanza veloce nel creare componenti da zero. Tuttavia, deve ancora chiamare il tuo codice quando lo crea. Quindi se il tuo costruttore, componenteDidMount, render, il codice ecc è costoso, allora rallenterà notevolmente mostrando il componente. Significa anche che non puoi usare questo con componenti stateful in cui vuoi che lo stato sia preservato quando nascosto (e ripristinato quando visualizzato). L’unico vantaggio è che il componente nascosto non viene creato affatto finché non viene selezionato. Quindi i componenti nascosti non ritarderanno il caricamento iniziale della pagina. Ci possono anche essere casi in cui si desidera che un componente stateful si resetta quando commutato. In tal caso questa è la tua migliore opzione.

Opzione 2: rendering condizionale nel bambino

Questo crea entrambi i componenti una volta. Quindi cortocircuiti il ​​resto del codice di rendering se il componente è nascosto. Puoi anche mettere in corto circuito altre logiche in altri metodi usando il puntello visibile. Notare console.log nella pagina codepen. https://codepen.io/Kelnor/pen/YrKaWZ?editors=0011

 class LoginControl extends React.Component { constructor(props) { super(props); this.handleLoginClick = this.handleLoginClick.bind(this); this.handleLogoutClick = this.handleLogoutClick.bind(this); this.state = {isLoggedIn: false}; } handleLoginClick() { this.setState({isLoggedIn: true}); } handleLogoutClick() { this.setState({isLoggedIn: false}); } render() { const isLoggedIn = this.state.isLoggedIn; return ( 
); } } class LogoutButton extends React.Component{ constructor(props, context){ super(props, context) console.log('created logout button'); } render(){ if(!this.props.isLoggedIn){ return null; } return ( ); } } class LoginButton extends React.Component{ constructor(props, context){ super(props, context) console.log('created login button'); } render(){ if(this.props.isLoggedIn){ return null; } return ( ); } } function UserGreeting(props) { return

Welcome back!

; } function GuestGreeting(props) { return

Please sign up.

; } function Greeting(props) { const isLoggedIn = props.isLoggedIn; if (isLoggedIn) { return ; } return ; } ReactDOM.render( , document.getElementById('root') );

Ora, se la logica di inizializzazione è veloce e i bambini sono privi di stato, non si noterà alcuna differenza in termini di prestazioni o funzionalità. Tuttavia, perché fare in modo che React crei un componente completamente nuovo ogni volta? Tuttavia, se l’inizializzazione è costosa, l’opzione 1 verrà eseguita ogni volta che si triggers un componente che rallenta la pagina durante il passaggio. L’opzione 2 eseguirà tutte le impostazioni del componente al primo caricamento della pagina. Rallentando quel primo carico. Dovrebbe notare di nuovo. Se stai mostrando il componente una volta sola in base a una condizione e non lo attivi o vuoi reimpostarlo quando viene triggersto, l’opzione 1 va bene e probabilmente l’opzione migliore.

Se il caricamento lento della pagina è un problema, significa che hai un codice costoso in un metodo del ciclo di vita e generalmente non è una buona idea. È ansible, e probabilmente dovrebbe, risolvere il lento caricamento della pagina spostando il costoso codice dai metodi del ciclo di vita. Spostalo in una funzione asincrona avviata da ComponentDidMount e fai in modo che la richiamata sia inserita in una variabile di stato con setState (). Se la variabile di stato è nullo e il componente è visibile, fare in modo che la funzione di rendering restituisca un segnaposto. Altrimenti esegui il rendering dei dati. In questo modo la pagina si caricherà rapidamente e popolerà le tabs durante il caricamento. Puoi anche spostare la logica nel genitore e spingere i risultati ai bambini come oggetti di scena. In questo modo puoi dare la priorità a quali tabs vengono caricate per prime. Oppure memorizzare i risultati nella cache e eseguire la logica solo la prima volta che viene mostrato un componente.

Opzione 3: Nascondere la class

Nascondere la class è probabilmente la più facile da implementare. Come accennato, basta creare una class CSS con display: none e assegnare la class basata sul puntello. Lo svantaggio è che viene chiamato l’intero codice di ogni componente nascosto e tutti i componenti nascosti sono collegati al DOM. (L’opzione 1 non crea affatto i componenti nascosti e l’opzione 2 cortocircuita il codice non necessario quando il componente è nascosto e rimuove completamente il componente dal DOM.) Sembra che questo sia più veloce alla commutazione della visibilità secondo alcuni test fatti dai commentatori altre risposte ma non posso parlarne.

Opzione 4: un componente ma cambia puntelli. O forse nessun componente e cache HTML.

Questo non funzionerà per ogni applicazione ed è fuori tema perché non si tratta di hide i componenti, ma potrebbe essere una soluzione migliore per alcuni casi d’uso che hide. Diciamo che hai tabs. Potrebbe essere ansible scrivere un Componente di Reazione e usare semplicemente gli oggetti di scena per cambiare ciò che viene visualizzato nella scheda. È anche ansible salvare il JSX per specificare le variabili e utilizzare un supporto per decidere quale JSX restituire nella funzione di rendering. Se il JSX deve essere generato, fallo e memorizzalo nel genitore e invia quello corretto come sostegno. Oppure genera nel bambino e lo memorizza nella cache nello stato del bambino e usa gli oggetti per selezionare quello attivo.

Questo è un buon modo per utilizzare il DOM virtuale:

Reagire:

  var Comp = React.createClass({ getInitialState: function(){ return {hide: false}; }, toggle: function(){ this.setState({hide: !this.state.hide}); }, render: function() { return 
Hi there
; } }); ReactDOM.render( , document.getElementById('container') );

CSS

  .hide-true { display: none; } 

Fiddle qui

Se ti piacerebbe vedere come TOGGLE il display di un componente controlla questo violino.

http://jsfiddle.net/mnoster/kb3gN/16387/

 var Search = React.createClass({ getInitialState: function() { return { shouldHide:false }; }, onClick: function() { console.log("onclick"); if(!this.state.shouldHide){ this.setState({ shouldHide: true }) }else{ this.setState({ shouldHide: false }) } }, render: function() { return ( 

yoyoyoyoyo

); } }); ReactDOM.render( , document.getElementById('container'));

In alcuni casi, un componente di ordine superiore potrebbe essere utile:

Crea un componente di ordine superiore:

 export var HidableComponent = (ComposedComponent) => class extends React.Component { render() { if ((this.props.shouldHide!=null && this.props.shouldHide()) || this.props.hidden) return null; return ; } }; 

Estendi il tuo componente:

 export const MyComp= HidableComponent(MyCompBasic); 

Quindi puoi usarlo in questo modo:

   

Questo riduce un po ‘lo standard e impone di attenersi alle convenzioni di denominazione, tuttavia tieni presente che MyComp sarà ancora istanziato – il modo di omettere è stato menzionato prima:

{ !hidden && }

Comincio con questa affermazione del team di React:

In React, puoi creare componenti distinti che incapsulano il comportamento di cui hai bisogno. Quindi, puoi renderne solo alcuni, a seconda dello stato della tua applicazione.

Il rendering condizionale in React funziona nello stesso modo in cui le condizioni funzionano in JavaScript. Utilizza gli operatori JavaScript come if o l’operatore condizionale per creare elementi che rappresentano lo stato corrente e lascia che React aggiorni l’interfaccia utente per abbinarli.

Fondamentalmente devi mostrare il componente quando il pulsante viene cliccato, puoi farlo in due modi, usando puro React o usando CSS, usando la modalità React pura, puoi fare qualcosa di simile al codice nel tuo caso, quindi nella prima analisi, i risultati non vengono visualizzati come hideResults è true , ma facendo clic sul pulsante, lo stato cambierà e hideResults è false e il componente verrà reso nuovamente con le nuove condizioni di valore, questo è un uso molto comune della modifica della visualizzazione dei componenti in React …

 var Search = React.createClass({ getInitialState: function() { return { hideResults: true }; }, handleClick: function() { this.setState({ hideResults: false }); }, render: function() { return ( 
{ !this.state.hideResults && }
); } }); var Results = React.createClass({ render: function() { return (
Some Results
); } }); ReactDOM.render(, document.body);

Se vuoi approfondire lo studio del rendering condizionale in React, dai un’occhiata qui .

Le migliori pratiche sono sotto secondo la documentazione:

  {this.state.showFooter && 
}

Renderizza l’elemento solo quando lo stato è valido.

  class FormPage extends React.Component{ constructor(props){ super(props); this.state = { hidediv: false } } handleClick = (){ this.setState({ hidediv: true }); } render(){ return( 
); } }