Mostra o nascondi l'elemento in React


532

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

var Search= React.createClass({
    handleClick: function (event) {
        console.log(this.prop);
    },
    render: function () {
        return (
            <div className="date-range">
                <input type="submit" value="Search" onClick={this.handleClick} />
            </div>
        );
    }
});

var Results = React.createClass({
    render: function () {
        return (
            <div id="results" className="search-results">
                Some Results
            </div>
        );
    }
});

React.renderComponent(<Search /> , document.body);

11
Il commento accettato utilizza una nuova tecnologia per fare ciò che la tecnologia esistente a livello nativo può fare sia in modo più semplice, più rapido e condivisibile con altre lingue e librerie. Gestire questo con CSS standard è quasi sicuramente la risposta migliore.
John Haugeland,

13
@JohnHaugeland, la migliore risposta quando si utilizza React framework è la risposta accettata, che utilizza tutto lo stile React, che ha funzioni di pulizia che in alcuni casi è necessario eseguire. Non è buona pratica avere componenti che si nascondono solo al buio. Se mescoli cose, è meglio che tu sia nativo, che è sempre più veloce di ogni altra cosa.
Claudiu Hojda,

4
No, non lo è davvero. Usare reagire per reinventare i CSS è una cattiva idea.
John Haugeland,

8
Inoltre, sembra che tu abbia completamente perso il punto di quello che ho detto, che era usare CSS per nascondere e mostrare l'elemento, piuttosto che usare React per rimuoverlo fisicamente. È possibile utilizzare Reagire ad usare i CSS per nascondere e mostrare l'elemento altrettanto facilmente: <div style = {{display: this.props.example}} />.
John Haugeland,

5
@ClaudiuHojda con componenti nascosti nell'oscurità è in realtà una pratica molto buona in alcuni casi, sto pensando alla navigazione reattiva, dove hai bisogno dei link per rimanere nell'HTML anche se sono nascosti con css
Toni Leigh

Risposte:


545

Reagire intorno al 2020

Nel onClickcallback, chiamare la funzione setter del hook di stato per aggiornare lo stato e ripetere il rendering:

const Search = () => {
  const [showResults, setShowResults] = React.useState(false)
  const onClick = () => setShowResults(true)
  return (
    <div>
      <input type="submit" value="Search" onClick={onClick} />
      { showResults ? <Results /> : null }
    </div>
  )
}

const Results = () => (
  <div id="results" className="search-results">
    Some Results
  </div>
)

ReactDOM.render(<Search />, document.querySelector("#container"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>

<div id="container">
  <!-- This element's contents will be replaced with your component. -->
</div>

JSFiddle

Reagire intorno al 2014

La chiave è aggiornare lo stato del componente nel gestore clic utilizzando setState. Quando vengono applicati i cambiamenti di stato, il rendermetodo viene richiamato nuovamente con il nuovo stato:

var Search = React.createClass({
    getInitialState: function() {
        return { showResults: false };
    },
    onClick: function() {
        this.setState({ showResults: true });
    },
    render: function() {
        return (
            <div>
                <input type="submit" value="Search" onClick={this.onClick} />
                { this.state.showResults ? <Results /> : null }
            </div>
        );
    }
});

var Results = React.createClass({
    render: function() {
        return (
            <div id="results" className="search-results">
                Some Results
            </div>
        );
    }
});

ReactDOM.render( <Search /> , document.getElementById('container'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.2/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/15.6.2/react-dom.min.js"></script>

<div id="container">
  <!-- This element's contents will be replaced with your component. -->
</div>

JSFiddle


3
Sì, buon punto su stato vs oggetti di scena. Un modo migliore per farlo dovrebbe essere come nel tutorial qui, dove la barra di ricerca e la tabella dei risultati sono fratelli invece di mettere i risultati all'interno della ricerca: facebook.github.io/react/docs/thinking-in-react.html
Douglas

53
Come notato nell'altra risposta, l'inserimento / la cancellazione sono molto più lenti del semplice mascheramento di classe.
John Haugeland,

4
Penso che i commenti di Johns debbano essere rivisti. Sono andato con la risposta voluta e questo era pulito e "sentito" più reagire come. Tuttavia, non sono stato in grado di impostare gli stati iniziali e qualsiasi cosa utile su un componente non montato. Sto invece cercando di usare CSS per nascondere le cose. Gli ascoltatori di componenti non montati falliranno silenziosamente e questo mi ha causato una grande perdita di tempo oggi.
sbarcò il

Ciò significa che la reazione restituirà il componente quando lo stile cambia (è impostato per mostrare / nascondere)!?
alex

@Douglas se non l'ho perso, in questo modo non è possibile tornare all'originale. Immagino che l'OP potrebbe non averlo voluto, ma come posso includerlo?
Il worm

221
<style type="text/css">
    .hidden { display:none; }
</style>
render: function() {
    return (
      <div className={this.props.shouldHide ? 'hidden' : ''}>
        This will be hidden if you set <tt>props.shouldHide</tt> 
        to something truthy.
      </div>
    );
}

// or in more modern JS and stateless react
const Example = props => <div className={props.shouldHide}/>Hello</div>

12
È meglio restituire condizionalmente null come nella risposta di Douglas. Ciò consente a React di rimuoverlo completamente dal DOM. Nel tuo caso il div e i suoi contenuti sono ancora nel DOM, ma non vengono visualizzati. Ciò può avere implicazioni sulle prestazioni.
pmont,

125
Le implicazioni sulle prestazioni sono molto peggiori per l'aggiunta e la rimozione di un elemento dom di quanto non lo siano per nasconderlo e mostrarlo. Sono consapevole della differenza tra il suo approccio e il mio e credo che tu abbia esattamente sbagliato. Considerare il tempo necessario per definire le "implicazioni sulle prestazioni" e quindi misurarlo.
John Haugeland

6
"I reflow sono garantiti con Aggiungi / Rimuovi" - Non con elementi assolutamente posizionati, il che è il modo in cui Famous ottiene le sue incredibili prestazioni. Ma fai un punto valido sulle metriche.
pmont,

9
per quello che vale, questo è menzionato nei documenti di reazione qui: facebook.github.io/react/docs/…
Brad Parks

85
Quindi ho appena provato a restituire null vs. impostare una classe nascosta con 161 nodi dom abbastanza grandi. È molto più veloce usando una classe che rimuovere il nodo.
Jonathan Rowny,

120

Ecco una sintassi alternativa per l'operatore ternario:

{ this.state.showMyComponent ? <MyComponent /> : null }

è equivalente a:

{ this.state.showMyComponent && <MyComponent /> }

Magra perché


Anche sintassi alternativa con display: 'none';

<MyComponent style={this.state.showMyComponent ? {} : { display: 'none' }} />

Tuttavia, se si fa un uso eccessivo display: 'none', questo porta all'inquinamento da DOM e alla fine rallenta l'applicazione.


Avvertimento! Utilizzare l'approccio "doppia e commerciale (&&)" solo per i valori bool. {this.state.myComponents.length && <MyComponent />} visualizzerà 0, se myComponents svuota l'array (ad esempio)
Mega Proger il

57

Ecco il mio approccio.

import React, { useState } from 'react';

function ToggleBox({ title, children }) {
  const [isOpened, setIsOpened] = useState(false);

  function toggle() {
    setIsOpened(wasOpened => !wasOpened);
  }

  return (
    <div className="box">
      <div className="boxTitle" onClick={toggle}>
        {title}
      </div>
      {isOpened && (
        <div className="boxContent">
          {children}
        </div>
      )}
    </div>
  );
}

Nel codice sopra, per raggiungere questo obiettivo, sto usando un codice come:

{opened && <SomeElement />}

Ciò renderà SomeElementsolo 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 && <SomeElement />; // will output SomeElement if `opened` is true, will output false otherwise (and false will be ignored by react during rendering)
// be careful with 'falsy' values eg
const someValue = 0;
someValue && <SomeElement /> // will output 0, which will be rednered by react
// it'll be better to:
!!someValue && <SomeElement /> // will render nothing as we cast the value to boolean

Ragioni per l'utilizzo di questo approccio anziché CSS 'display: none';

  • Mentre potrebbe essere "più economico" nascondere un elemento con CSS - in tal caso l'elemento "nascosto" è ancora "vivo" nel mondo reattivo (il che potrebbe renderlo effettivamente molto più costoso)
    • significa che se i puntelli dell'elemento genitore (ad es. <TabView>) cambieranno - anche se vedi solo una scheda, tutte e 5 le schede verranno ridigitate
    • l'elemento nascosto potrebbe avere ancora alcuni metodi del ciclo di vita in esecuzione - ad es. potrebbe recuperare alcuni dati dal server dopo ogni aggiornamento anche se non è visibile
    • l'elemento nascosto potrebbe arrestare in modo anomalo l'app se riceverà dati errati. Potrebbe accadere in quanto è possibile "dimenticare" i nodi invisibili durante l'aggiornamento dello stato
    • potresti erroneamente impostare uno stile di "visualizzazione" errato quando rendi visibile l'elemento, ad es. alcuni div sono 'display: flex' per impostazione predefinita, ma imposterai 'display: block' per errore con il display: invisible ? 'block' : 'none'quale potrebbe interrompere il layout
    • l'utilizzo someBoolean && <SomeNode />è molto semplice da capire e ragionare, specialmente se la tua logica relativa alla visualizzazione di qualcosa diventa complessa
    • in molti casi, si desidera "ripristinare" lo stato dell'elemento quando riappare. per esempio. potresti avere un dispositivo di scorrimento che desideri impostare sulla posizione iniziale ogni volta che viene mostrato. (se questo è il comportamento desiderato per mantenere lo stato dell'elemento precedente, anche se nascosto, quale IMO è raro - prenderei davvero in considerazione l'uso dei CSS se ricordare questo stato in un modo diverso sarebbe complicato)

2
Questo è un ottimo esempio! Una piccola cosa, boxContent dovrebbe essere className = "boxContent"
Bhetzie,

5
C'è un bug proprio qui: this.setState({isOpened: !isOpened});. Non dipendere dallo stato stesso, quando si modifica lo stato. Ecco un buon esempio: reactjs.org/docs/... Così dovrebbe essere: this.setState( s => ({isOpened: !s.isOpened}) ). Nota la funzione freccia all'interno di setState.
Arcol,

Hai qualche sorgente / benchmark / esempio che confermi questo "Se imposti display: none - l'elemento è ancora reso da reattivo e aggiunto al DOM - che può avere un impatto negativo sulle prestazioni". ?
Neiya,

@neiya no. I CSS potrebbero essere più performanti con piccoli elementi, ma abbastanza spesso si desidera rendere facoltativamente grandi parti di contenuto, ad es. scheda. Inoltre, mentre alcuni elementi sono nascosti con CSS - è ancora vivo nel mondo delle reazioni. Significa che potrebbe aggiornare il suo stato, recuperare alcuni dati ecc. Che potrebbero essere costosi e portare a comportamenti imprevisti. Ed è IMO in realtà molto semplice da implementare.
pie6k


11

Ho creato un piccolo componente che gestisce questo per te: reazioni-toggle-display

Imposta l'attributo di stile in display: none !importantbase a hideo showoggetti 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 (
            <div>
                <input type="submit" value="Search" onClick={this.onClick} />
                <ToggleDisplay show={this.state.showResults}>
                    <Results />
                </ToggleDisplay>
            </div>
        );
    }
});

var Results = React.createClass({
    render: function() {
        return (
            <div id="results" className="search-results">
                Some Results
            </div>
        );
    }
});

React.renderComponent(<Search />, document.body);

10

Ci sono già molte risposte fantastiche, ma non credo che siano state spiegate molto bene e molti dei metodi forniti contengono alcuni trucchi che potrebbero far inciampare le persone. Quindi esaminerò i tre modi principali (più un'opzione off-topic) per fare questo e spiegare i pro ei contro. Lo scrivo principalmente perché l'opzione 1 è stata raccomandata molto e ci sono molti potenziali problemi con quell'opzione se non usata correttamente.

Opzione 1: rendering condizionale nel genitore.

Non mi piace questo metodo a meno che tu non voglia renderizzare il componente una sola volta e lasciarlo lì. Il problema è che farà reagire creando il componente da zero ogni volta che si attiva / disattiva la visibilità. Ecco l'esempio. LogoutButton o LoginButton vengono sottoposti a rendering condizionale nel LoginControl padre. Se esegui questo, noterai che il costruttore viene chiamato su 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 = <LogoutButton onClick={this.handleLogoutClick} />;
    } else {
      button = <LoginButton onClick={this.handleLoginClick} />;
    }

    return (
      <div>
        <Greeting isLoggedIn={isLoggedIn} />
        {button}
      </div>
    );
  }
}

class LogoutButton extends React.Component{
  constructor(props, context){
    super(props, context)
    console.log('created logout button');
  }
  render(){
    return (
      <button onClick={this.props.onClick}>
        Logout
      </button>
    );
  }
}

class LoginButton extends React.Component{
  constructor(props, context){
    super(props, context)
    console.log('created login button');
  }
  render(){
    return (
      <button onClick={this.props.onClick}>
        Login
      </button>
    );
  }
}

function UserGreeting(props) {
  return <h1>Welcome back!</h1>;
}

function GuestGreeting(props) {
  return <h1>Please sign up.</h1>;
}

function Greeting(props) {
  const isLoggedIn = props.isLoggedIn;
  if (isLoggedIn) {
    return <UserGreeting />;
  }
  return <GuestGreeting />;
}

ReactDOM.render(
  <LoginControl />,
  document.getElementById('root')
);

Ora React è abbastanza veloce nel creare componenti da zero. Tuttavia, deve ancora chiamare il codice durante la creazione. Quindi se il tuo costruttore, componentDidMount, render, ecc. Codice è costoso, allora rallenterà in modo significativo mostrando il componente. Significa anche che non è possibile utilizzarlo con componenti con stato in cui si desidera conservare lo stato quando nascosto (e ripristinato quando visualizzato). L'unico vantaggio è che il componente nascosto non viene creato fino a quando non viene selezionato. Quindi i componenti nascosti non ritarderanno il caricamento della pagina iniziale. Ci possono anche essere casi in cui VUOI reimpostare un componente con stato per ripristinare quando attivato. Nel qual caso questa è la tua migliore opzione.

Opzione 2: rendering condizionale nel bambino

Questo crea entrambi i componenti una volta. Quindi cortocircuita il resto del codice di rendering se il componente è nascosto. Puoi anche cortocircuitare 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 (
      <div>
        <Greeting isLoggedIn={isLoggedIn} />
        <LoginButton isLoggedIn={isLoggedIn} onClick={this.handleLoginClick}/>
        <LogoutButton isLoggedIn={isLoggedIn} onClick={this.handleLogoutClick}/>
      </div>
    );
  }
}

class LogoutButton extends React.Component{
  constructor(props, context){
    super(props, context)
    console.log('created logout button');
  }
  render(){
    if(!this.props.isLoggedIn){
      return null;
    }
    return (
      <button onClick={this.props.onClick}>
        Logout
      </button>
    );
  }
}

class LoginButton extends React.Component{
  constructor(props, context){
    super(props, context)
    console.log('created login button');
  }
  render(){
    if(this.props.isLoggedIn){
      return null;
    }
    return (
      <button onClick={this.props.onClick}>
        Login
      </button>
    );
  }
}

function UserGreeting(props) {
  return <h1>Welcome back!</h1>;
}

function GuestGreeting(props) {
  return <h1>Please sign up.</h1>;
}

function Greeting(props) {
  const isLoggedIn = props.isLoggedIn;
  if (isLoggedIn) {
    return <UserGreeting />;
  }
  return <GuestGreeting />;
}

ReactDOM.render(
  <LoginControl />,
  document.getElementById('root')
);

Ora, se la logica di inizializzazione è rapida e i figli sono apolidi, allora non vedrai alcuna differenza in termini di prestazioni o funzionalità. Tuttavia, perché fare in modo che React crei un nuovo componente ogni interruttore? Se l'inizializzazione è costosa, l'opzione 1 verrà eseguita ogni volta che si attiva o disattiva un componente che rallenta la pagina quando si cambia. L'opzione 2 eseguirà tutti gli init del componente al caricamento della prima pagina. Rallentando quel primo carico. Dovrebbe notare di nuovo. Se stai solo mostrando il componente una volta in base a una condizione e non attivandolo o se vuoi che venga ripristinato quando attivato, l'opzione 1 va bene e probabilmente l'opzione migliore.

Se il caricamento lento della pagina è comunque un problema, significa che hai un codice costoso in un metodo del ciclo di vita e che generalmente non è una buona idea. Puoi, e probabilmente dovresti, risolvere il lento caricamento della pagina spostando il costoso codice dai metodi del ciclo di vita. Spostalo in una funzione asincrona che è stata avviata da ComponentDidMount e fai in modo che il callback lo inserisca in una variabile di stato con setState (). Se la variabile di stato è nulla e il componente è visibile, fare in modo che la funzione di rendering restituisca un segnaposto. Altrimenti renderizza i dati. In questo modo la pagina si caricherà rapidamente e popolerà le schede mentre vengono caricate. Puoi anche spostare la logica nel genitore e inviare i risultati ai bambini come oggetti di scena. In questo modo puoi dare la priorità a quali schede vengono caricate per prime. Oppure memorizza nella cache i risultati ed esegui la logica solo la prima volta che viene mostrato un componente.

Opzione 3: nascondere la classe

Nascondere la classe è probabilmente il più facile da implementare. Come accennato, devi solo creare una classe CSS con display: none e assegnare la classe in base a prop. Il rovescio della medaglia è l'intero codice di ogni componente nascosto chiamato e tutti i componenti nascosti sono collegati al DOM. (L'opzione 1 non crea affatto i componenti nascosti. E l'opzione 2 mette in cortocircuito il codice non necessario quando il componente è nascosto e rimuove completamente il componente dal DOM.) Sembra che questo sia più veloce nel cambiare la visibilità secondo alcuni test effettuati dai commentatori su altre risposte ma non posso parlarne.

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

Questo non funzionerà per tutte le applicazioni ed è fuori tema perché non si tratta di nascondere i componenti, ma potrebbe essere una soluzione migliore per alcuni casi d'uso che nascondere. Supponiamo che tu abbia delle schede. Potrebbe essere possibile scrivere un componente React e usare solo gli oggetti di scena per cambiare ciò che viene visualizzato nella scheda. È inoltre possibile salvare JSX in variabili di stato e utilizzare un prop per decidere quale JSX restituire nella funzione di rendering. Se il JSX deve essere generato, fallo e memorizzalo nella cache del genitore e invia quello corretto come prop. Oppure genera nel figlio e memorizzalo nella cache nello stato del figlio e usa i puntelli per selezionare quello attivo.


9

Questo è un bel modo di usare il DOM virtuale :

class Toggle extends React.Component {
  state = {
    show: true,
  }

  toggle = () => this.setState((currentState) => ({show: !currentState.show}));

  render() {
    return (
      <div>
        <button onClick={this.toggle}>
          toggle: {this.state.show ? 'show' : 'hide'}
        </button>    
        {this.state.show && <div>Hi there</div>}
      </div>
     );
  }
}

Esempio qui

Utilizzando i ganci React:

const Toggle = () => {
  const [show, toggleShow] = React.useState(true);

  return (
    <div>
      <button
        onClick={() => toggleShow(!show)}
      >
        toggle: {show ? 'show' : 'hide'}
      </button>    
      {show && <div>Hi there</div>}
    </div>
  )
}

Esempio qui


Mi piace questa risposta magra. Peccato che il violino non scappasse.
Juan Lanus,

Come menzionato in una risposta precedente, non dovresti dipendere dallo stato inthis.setState() .
Dan Dascalescu,

8

Si imposta un valore booleano nello stato (ad esempio "show)", quindi si:

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

return <div style={style}>...</div>

Ho provato questo, ma l'evento click non ha cambiato il css in display block. Mi sono perso esattamente su come realizzarlo. Ulteriori suggerimenti?
user1725382

1
Ciò implica apportare modifiche attive alla tabella delle regole di stile. È molto meglio avere un'unica regola esistente che puoi attivare e disattivare, che non fa parte delle proprietà dinamiche del nodo dom.
John Haugeland,

1
Non importa davvero se usi una classe o uno stile qui ... sembri molto impegnato in questo.
Brigand,

2
L'uso di una classe è più veloce di un paio di ordini di grandezza. Buono a sapersi.
Jason Rice,

1
Potrei semplicemente usare i nomi delle classi condizionali con: github.com/JedWatson/classnames
backdesk

7

Le migliori pratiche sono riportate di seguito in base alla documentazione:

{this.state.showFooter && <Footer />}

Rendering dell'elemento solo quando lo stato è valido.


Questa risposta è già stata fornita un anno prima, quindi è OK eliminarla ora.
Dan Dascalescu,

5
class Toggle extends React.Component {
  state = {
    show: true,
  }

  render() {
    const {show} = this.state;
    return (
      <div>
        <button onClick={()=> this.setState({show: !show })}>
          toggle: {show ? 'show' : 'hide'}
        </button>    
        {show && <div>Hi there</div>}
      </div>
     );
  }
}

4
   class FormPage extends React.Component{
      constructor(props){
           super(props);
           this.state = {
             hidediv: false
           }
      }

     handleClick = (){
       this.setState({
          hidediv: true
        });
      }

      render(){
        return(
        <div>
          <div className="date-range" hidden = {this.state.hidediv}>
               <input type="submit" value="Search" onClick={this.handleClick} />
          </div>
          <div id="results" className="search-results" hidden = {!this.state.hidediv}>
                        Some Results
           </div>
        </div>
        );
      }
  }

4

Comincio con questa affermazione del team React:

In React, è possibile creare componenti distinti che incapsulano il comportamento necessario. Quindi, puoi renderizzare solo alcuni di essi, a seconda dello stato della tua applicazione.

Il rendering condizionale in React funziona allo stesso modo delle condizioni in JavaScript. Usa 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 farli corrispondere.

Fondamentalmente devi mostrare il componente quando fai clic sul pulsante, puoi farlo in due modi, usando React puro o usando CSS, usando puro React, puoi fare qualcosa come il codice sottostante nel tuo caso, quindi nella prima esecuzione, i risultati non vengono visualizzati così come hideResultssono true, ma facendo clic sul pulsante, lo stato cambierà e lo hideResultssarà falsee il componente verrà nuovamente visualizzato con le nuove condizioni di valore, questo è un uso molto comune della modifica della vista dei componenti in React ...

var Search = React.createClass({
  getInitialState: function() {
    return { hideResults: true };
  },

  handleClick: function() {
    this.setState({ hideResults: false });
  },

  render: function() {
    return (
      <div>
        <input type="submit" value="Search" onClick={this.handleClick} />
        { !this.state.hideResults && <Results /> }
      </div> );
  }

});

var Results = React.createClass({
  render: function() {
    return (
    <div id="results" className="search-results">
      Some Results
    </div>);
   }
});

ReactDOM.render(<Search />, document.body);

Se vuoi studiare ulteriormente il rendering condizionale in React, dai un'occhiata qui .


1
questo dovrebbe essere il modo più elegante!
quinto

4

Semplice esempio di nascondere / mostrare con React Hooks: (srry about no fiddle)

const Example = () => {

  const [show, setShow] = useState(false);

  return (
    <div>
      <p>Show state: {show}</p>
      {show ? (
        <p>You can see me!</p>
      ) : null}
      <button onClick={() => setShow(!show)}>
    </div>
  );

};

export default Example;

2
può essere più semplice semplicemente {mostrare? 1: 2}
Piotr Żak il

3

Se vuoi vedere come ATTIVARE la visualizzazione 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 (
      <div>
        <button onClick={this.onClick}>click me</button>
        <p className={this.state.shouldHide ? 'hidden' : ''} >yoyoyoyoyo</p>
      </div>
    );
}
});

ReactDOM.render( <Search /> , document.getElementById('container'));

3

Un metodo semplice per mostrare / nascondere elementi in React usando Hooks

const [showText, setShowText] = useState(false);

Ora, aggiungiamo un po 'di logica al nostro metodo di rendering:

{showText && <div>This text will show!</div>}

E

onClick={() => setShowText(!showText)}

Buon lavoro.


2

In alcuni casi il 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 <ComposedComponent {...this.props}  />;
    }
};

Estendi il tuo componente:

export const MyComp= HidableComponent(MyCompBasic);

Quindi puoi usarlo in questo modo:

<MyComp hidden={true} ... />
<MyComp shouldHide={this.props.useSomeFunctionHere} ... />

Ciò riduce un po 'la piastra di comando e impone di attenersi alle convenzioni di denominazione, tuttavia tieni presente che MyComp verrà ancora istanziato - il modo di omettere è stato menzionato in precedenza:

{ !hidden && <MyComp ... /> }


1

Usa il modulo rc-if-else

npm install --save rc-if-else
import React from 'react';
import { If } from 'rc-if-else';

class App extends React.Component {
    render() {
        return (
            <If condition={this.props.showResult}>
                Some Results
            </If>
        );
    }
}

1

Usa ref e manipola CSS

Un modo potrebbe essere quello di utilizzare React refe manipolare la classe CSS utilizzando l'API del browser. Il suo vantaggio è evitare di ripetere il rendering in React se l'unico scopo è nascondere / mostrare alcuni elementi DOM con un clic di un pulsante.

// Parent.jsx
import React, { Component } from 'react'

export default class Parent extends Component {
    constructor () {    
        this.childContainer = React.createRef()
    }

    toggleChild = () => {
        this.childContainer.current.classList.toggle('hidden')
    }

    render () {
        return (
            ...

            <button onClick={this.toggleChild}>Toggle Child</button>
            <div ref={this.childContainer}>
                <SomeChildComponent/>
            </div>

            ...
        );
    }
}


// styles.css
.hidden {
    display: none;
}

PS: correggimi se sbaglio. :)


Esempio di codesandbox.io creato, qui: utgzx.csb.app , il codice è su codesandbox.io/embed/react-show-hide-with-css-utgzx
PatS

0

Se usi bootstrap 4, puoi nascondere l'elemento in quel modo

className={this.state.hideElement ? "invisible" : "visible"}

0

Questo può essere ottenuto anche in questo modo (modo molto semplice)

 class app extends Component {
   state = {
     show: false
   };
 toggle= () => {
   var res = this.state.show;
   this.setState({ show: !res });
 };
render() {
  return(
   <button onClick={ this.toggle }> Toggle </button>
  {
    this.state.show ? (<div> HELLO </div>) : null
  }
   );
     }

Si prega di leggere sull'impostazione di "stato in base allo stato precedente" su reagjs.org/docs/react-component.html#setstate . Inoltre, sarebbe bello correggere il rientro alla fine.
Dan Dascalescu,

0

questo esempio mostra come passare da un componente all'altro usando un interruttore che cambia dopo ogni 1 secondo

import React ,{Fragment,Component} from "react";
import ReactDOM from "react-dom";

import "./styles.css";

const Component1 = () =>(
  <div>
    <img 
src="https://i.pinimg.com/originals/58/df/1d/58df1d8bf372ade04781b8d4b2549ee6.jpg" />
   </div>
)

const Component2 = () => {
  return (
    <div>
       <img 
src="http://www.chinabuddhismencyclopedia.com/en/images/thumb/2/2e/12ccse.jpg/250px- 
12ccse.jpg" />
  </div>
   )

 }

 class App extends Component {
   constructor(props) {
     super(props);
    this.state = { 
      toggleFlag:false
     }
   }
   timer=()=> {
    this.setState({toggleFlag:!this.state.toggleFlag})
  }
  componentDidMount() {
    setInterval(this.timer, 1000);
   }
  render(){
     let { toggleFlag} = this.state
    return (
      <Fragment>
        {toggleFlag ? <Component1 /> : <Component2 />}
       </Fragment>
    )
  }
}


const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Cos'è lo strano URL dell'immagine? Puoi utilizzare un servizio di segnaposto per immagini standard come placeimg.com
Dan Dascalescu,

0

Usa questa sintassi snella e breve:

{ this.state.show && <MyCustomComponent /> }

Forse potresti espandere la tua sintassi snella e corta per spiegare come funziona. Oh aspetta, è stato fatto in una risposta 3 anni prima . Cosa riporta di nuovo al tavolo la tua risposta?
Dan Dascalescu,

0

Ecco la soluzione semplice, efficace e migliore con un componente di reazione senza classe per mostrare / nascondere gli elementi. Uso di React-Hooks che è disponibile nell'ultimo progetto create -eagire-app che utilizza React 16

import React, {useState} from 'react';
function RenderPara(){
const [showDetail,setShowDetail] = useState(false);

const handleToggle = () => setShowDetail(!showDetail);

return (
<React.Fragment>
    <h3>
        Hiding some stuffs 
    </h3>
    <button onClick={handleToggle}>Toggle View</button>
   {showDetail && <p>
        There are lot of other stuffs too
    </p>}
</React.Fragment>)

}  
export default RenderPara;

Happy Coding :)


0
//use ternary condition

{ this.state.yourState ? <MyComponent /> : null } 

{ this.state.yourState && <MyComponent /> }

{ this.state.yourState == 'string' ? <MyComponent /> : ''}

{ this.state.yourState == 'string' && <MyComponent /> }

//Normal condition

if(this.state.yourState){
 return <MyComponent />
}else{
  return null;
}

-1

È possibile utilizzare il file CSS

    var Results = React.createClass({
    render: function() {
        return (
            <div id="results" className={`search-results ${this.state.showResults ? 'show' : ''}`}>
                Some Results
            </div>
        );
    }
})

e nel file css

    .search-results {
     ...
     display: none
     &.show {
      display: block
   }
}

-1
var Search= React.createClass({
 getInitialState: () => { showResults: false },
 onClick: () => this.setState({ showResults: true }),
 render: function () {
   const { showResults } = this.state;
   return (
     <div className="date-range">
       <input type="submit" value="Search" onClick={this.handleClick} />
       {showResults && <Results />}
     </div>
   );
 }
});

var Results = React.createClass({
    render: function () {
        return (
            <div id="results" className="search-results">
                Some Results
            </div>
        );
    }
});

React.renderComponent(<Search /> , document.body);

1
Puoi spiegare cosa hai fatto e perché è meglio della risposta accettata?
Seblor,

-1
class App extends React.Component {
  state = {
    show: true
  };

  showhide = () => {
    this.setState({ show: !this.state.show });
  };

  render() {
    return (
      <div className="App">
        {this.state.show && 
          <img src={logo} className="App-logo" alt="logo" />
        }
        <a onClick={this.showhide}>Show Hide</a>
      </div>
    );
  }
}

Potete per favore aggiungere una spiegazione per una migliore comprensione? Grazie!
Shanteshwar Inde,

@ShanteshwarInde: questo duplica la stessa idea da una risposta precedente , incluso un uso errato di setState a seconda dello stato corrente. Vedere reazionijs.org/docs/react-component.html#setstate : "Se è necessario impostare lo stato in base allo stato precedente, leggere l'argomento del programma di aggiornamento".
Dan Dascalescu,

-1

var Search = React.createClass({
    getInitialState: function() {
        return { showResults: false };
    },
    onClick: function() {
        this.setState({ showResults: true });
    },
    render: function() {
        return (
            <div>
                <input type="checkbox" value="Search" onClick={this.onClick} />
                { this.state.showResults ? <Results /> : null }
            </div>
        );
    }
});

var Results = React.createClass({
    render: function() {
        return (
            <div id="results" className="search-results">
                <input type="text" />
            </div>
        );
    }
});

ReactDOM.render( <Search /> , document.getElementById('container'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.2/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/15.6.2/react-dom.min.js"></script>

<div id="container">
  <!-- This element's contents will be replaced with your component. -->
</div>


4
Mentre questo codice può rispondere alla domanda, fornendo un contesto aggiuntivo riguardo al perché e / o al modo in cui questo codice risponde alla domanda migliora il suo valore a lungo termine.
xiawi,

Cosa ha detto @xiawi. Inoltre, utilizzare al constposto di varquando si dichiarano le costanti.
Dan Dascalescu,
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.