Afficher ou masquer l'élément de Réagir

Je déconne avec React.js pour la première fois et ne peut pas trouver un moyen d'afficher ou de cacher quelque chose sur une page via l'événement click. Je ne charge aucune autre bibliothèque sur la page, donc je cherche une manière native en utilisant la bibliothèque React. C'est ce que j'ai jusqu'à présent. Je voudrais montrer les résultats div lorsque l'événement click incendies.

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);
301
demandé sur Damjan Pavlica 2014-07-01 09:17:00

14 réponses

La clé consiste à mettre à jour l'état du composant dans le gestionnaire de clics en utilisant setState. Lorsque les changements d'état sont appliqués, la méthode render est appelée à nouveau avec le nouvel état:

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'));

Http://jsfiddle.net/kb3gN/15084/

350
répondu Douglas 2016-06-22 01:39:47
<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>
    );
}
146
répondu John Haugeland 2016-06-22 01:51:31

Voici une syntaxe alternative pour l'opérateur ternaire:

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

Est équivalent à:

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

Lean pourquoi


Aussi une syntaxe alternative avec display: 'none';

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

Cependant, si vous utilisez trop display: 'none', cela entraîne une pollution DOM et ralentit finalement votre application.

67
répondu Lyubomir 2017-10-10 12:35:50

Voici mon approche en utilisant ES6. Bien que la réponse acceptée soit correcte, elle est assez dépassée.

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 (
      <div className="box">
        <div className="boxTitle" onClick={this.toggleBox}>
          {title}
        </div>
        {isOpened && children && (
          <div className="boxContent">
            {children}
          </div>
        )}
      </div>
    );
  }
}

ReactDOM.render((
  <ToggleBox title="Click me">
    <div>Some content</div>
  </ToggleBox>
), document.getElementById('app'));

Démo: http://jsfiddle.net/kb3gN/16688/

Il est préférable de rendre un élément uniquement si nécessaire plutôt que d'ajouter des classes css avec display: none. Si vous définissez display: none - l'élément est toujours rendu par react et ajouté à DOM - cela peut avoir un impact négatif sur les performances.

Imaginez que vous avez une page avec des onglets, où chaque onglet a beaucoup de contenu et où seulement 1 onglet est ouvert à la fois. Il est préférable de ne tenir dans le DOM que les éléments qui sont censés être affichés.

Dans le code ci-dessus, pour y parvenir, j'utilise du code comme:

{opened && <SomeElement />}

Qui ne rendra {[7] } que si opened est vrai. Cela fonctionne en raison de la façon dont JavaScript résout les conditions logiques:

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
26
répondu pie6k 2018-06-20 14:03:00

Avec la nouvelle version react 0.11, vous pouvez également renvoyer null pour n'avoir aucun contenu Rendu.

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

14
répondu squiddle 2014-07-18 16:54:11

J'ai créé un petit composant qui gère pour vous: https://www.npmjs.com/package/react-toggle-display

Il définit l'attribut style sur display: none !important en fonction des accessoires hide ou show.

Exemple d'utilisation:

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);
9
répondu ccnokes 2016-06-21 22:20:58

Vous définissez une valeur booléenne dans l'état (par exemple " afficher), puis faire:

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

return <div style={style}>...</div>
7
répondu FakeRainBrigand 2014-07-01 05:30:24

Il y a déjà plusieurs bonnes réponses, mais je ne pense pas qu'elles aient été très bien expliquées et plusieurs des méthodes données contiennent des pièges qui pourraient faire trébucher les gens. Donc, je vais passer en revue les trois façons principales (plus une option hors sujet) pour le faire et expliquer les avantages et les inconvénients. J'écris surtout ceci parce que L'Option 1 a été recommandée beaucoup et il y a beaucoup de problèmes potentiels avec cette option si elle n'est pas utilisée correctement.

Option 1: Rendu conditionnel dans le parent.

Je n'aime pas cette méthode sauf si vous allez seulement rendre le composant une fois et le laisser là. Le problème est qu'il provoquera react pour créer le composant à partir de zéro chaque fois que vous basculez la visibilité. Voici l'exemple. LogoutButton ou LoginButton sont rendus conditionnellement dans le LoginControl parent. Si vous exécutez ceci, vous remarquerez que le constructeur est appelé à chaque clic de bouton. 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')
);

Maintenant, React est assez rapide pour créer des composants à partir de zéro. Cependant, il doit toujours appeler votre code lors de sa création. Donc, si votre code constructeur, componentDidMount, render, etc est coûteux, il ralentira considérablement l'affichage du composant. Cela signifie également que vous ne pouvez pas l'utiliser avec des composants avec état où vous voulez que l'État soit préservé lorsqu'il est caché (et restauré lorsqu'il est affiché.) Le seul avantage est que le composant caché n'est pas créé du tout jusqu'à ce qu'il soit sélectionné. Donc, les composants cachés ne retarderont pas votre chargement initial de la page. Il peut également y avoir des cas où vous voulez qu'un composant avec État soit réinitialisé lorsqu'il est basculé. Dans ce cas, c'est votre meilleure option.

Option 2: Rendu conditionnel dans l'enfant

Cela crée les deux composants une fois. Court-circuite ensuite le reste du code de rendu si le composant est masqué. Vous pouvez également court circuiter d'autres logiques dans d'autres méthodes en utilisant le visible prop. Remarquez la console.journal de dans le codepen page. 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')
);

Maintenant, si la logique d'initialisation est rapide et que les enfants sont apatrides, vous ne verrez pas de différence de performance ou de fonctionnalité. Cependant, pourquoi faire React créer un tout nouveau composant chaque bascule de toute façon? Cependant, si l'initialisation est coûteuse, L'Option 1 l'exécutera chaque fois que vous basculerez un composant, ce qui ralentira la page lors de la commutation. L'Option 2 exécutera tous les inits du composant lors du chargement de la première page. Ralentir cette première charge. Devrait noter à nouveau. Si vous montrez simplement le composant une fois en fonction d'une condition et ne le basculez pas, ou si vous voulez le réinitialiser lorsque toggledm, alors L'Option 1 est bien et probablement la meilleure option.

Si le chargement lent de la page pose problème, cela signifie que vous avez un code coûteux dans une méthode de cycle de vie et que ce n'est généralement pas une bonne idée. Vous pouvez, et devriez probablement, résoudre le chargement lent de la page en déplacer le code coûteux hors des méthodes de cycle de vie. Déplacez - le vers une fonction asynchrone lancée par ComponentDidMount et demandez au callback de le placer dans une variable d'état avec setState(). Si la variable d'état est null et que le composant est visible, la fonction de rendu renvoie un espace réservé. Autrement rendre les données. De cette façon, la page se chargera rapidement et remplira les onglets au fur et à mesure qu'ils se chargeront. Vous pouvez également déplacer la logique dans le parent et pousser les résultats aux enfants comme accessoires. Que façon dont vous pouvez prioriser quels onglets sont chargés en premier. Ou mettre en cache les résultats et n'exécuter la logique que la première fois qu'un composant est affiché.

Option 3: Masquage De Classe

Le masquage de classe est probablement le plus facile à implémenter. Comme mentionné, vous créez simplement une classe CSS avec display: none et attribuez la classe basée sur prop. L'inconvénient est que le code entier de chaque composant caché est appelé et tous les composants cachés sont attachés au DOM. (L'Option 1 ne crée pas du tout les composants cachés. Et L'Option 2 court-circuite le code inutile lorsque le composant est caché et supprime complètement le composant du DOM.) Il semble que ce soit plus rapide à basculer la visibilité selon certains tests effectués par des commentateurs sur d'autres réponses, mais je ne peux pas en parler.

Option 4: Un composant mais changer les accessoires. Ou peut-être pas de composant du tout et cache HTML.

Celui-ci ne fonctionnera pas pour toutes les applications et il est hors sujet car il ne s'agit pas de cacher des composants, mais cela pourrait être mieux solution pour certains cas d'utilisation que de se cacher. Disons que vous avez d'onglets. Il pourrait être possible d'écrire un composant React et d'utiliser simplement les accessoires pour changer ce qui est affiché dans l'onglet. Vous pouvez également enregistrer le JSX dans les variables d'état et utiliser un accessoire pour décider quel JSX retourner dans la fonction de rendu. Si le JSX doit être généré, faites-le et mettez-le en cache dans le parent et envoyez le bon comme accessoire. Ou générer dans l'enfant et le mettre en cache dans l'état de l'enfant et utiliser des accessoires pour sélectionner l'actif un.

6
répondu Kelnor 2017-09-11 21:42:37

C'est une bonne façon d'utiliser le DOM virtuel:

Réagir:

            var Comp = React.createClass({
                getInitialState: function(){
                return {hide: false};
              },
              toggle: function(){
                this.setState({hide: !this.state.hide});
              },
              render: function() {
                return <div>
                        <button onClick={this.toggle}>toggle</button>    
                    <div className={'hide-' + this.state.hide}>Hi there</div>
                </div>;
              }
            });

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

CSS

            .hide-true  {
              display: none;
            }

Violon ici

4
répondu daniloprates 2016-07-03 17:27:20

Si vous souhaitez voir comment basculer l'affichage d'un composant checkout ce violon.

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'));
2
répondu Nicholas 2016-12-29 21:38:19

Dans certains cas, un composant d'ordre supérieur peut être utile:

Créer un composant d'ordre supérieur:

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}  />;
    }
};

Étendre votre propre composant:

export const MyComp= HidableComponent(MyCompBasic);

, Alors vous pouvez l'utiliser comme ceci:

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

Cela réduit un peu standard et impose de respecter les conventions de nommage, mais sachez que MyComp sera toujours instancié - la façon d'omettre a été mentionnée plus tôt:

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

1
répondu vinga 2016-11-13 08:57:45

Je commence par cette déclaration de L'équipe React:

Dans React, vous pouvez créer des composants distincts qui encapsulent le comportement vous avez besoin d'. Ensuite, vous pouvez afficher seulement certains d'entre eux, en fonction de la l'état de votre demande.

Le rendu conditionnel dans React fonctionne de la même manière que les conditions JavaScript. Utilisez des opérateurs JavaScript comme if ou le conditionnel pour créer des éléments représentant l'état actuel, et laisser React mettre à jour l'interface utilisateur pour correspondre ils.

Vous devez essentiellement montrer le composant lorsque le bouton est cliqué, vous pouvez le faire de deux façons, en utilisant Pure React ou en utilisant CSS, en utilisant Pure React way, vous pouvez faire quelque chose comme le code ci-dessous dans votre cas, donc dans la première exécution, les résultats ne s'affichent pas comme hideResults est true, mais en cliquant sur le bouton, Réagir...

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);

Si vous voulez faire une étude plus approfondie du rendu conditionnel dans React, jetez un oeil ici.

1
répondu Alireza 2017-06-16 09:42:13

La meilleure pratique est ci-dessous selon la documentation:

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

Rendre l'élément uniquement lorsque l'état est valide.

1
répondu Dynamic 2018-05-13 07:29:56
   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>
        );
      }
  }
1
répondu Akanksha gore 2018-08-23 13:17:27