Afficher ou masquer l'élément dans React

532

Je joue avec React.js pour la première fois et je ne trouve pas de moyen d'afficher ou de masquer quelque chose sur une page via un événement de clic. Je ne charge aucune autre bibliothèque sur la page, je cherche donc une manière native d'utiliser la bibliothèque React. C'est ce que j'ai jusqu'à présent. Je voudrais afficher les résultats div lorsque l'événement click se déclenche.

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);
user1725382
la source
11
Le commentaire accepté utilise une nouvelle technologie pour faire ce que la technologie existante au niveau natif peut faire à la fois plus facilement, plus rapidement et de manière plus partagée avec d'autres langues et bibliothèques. Gérer cela avec du CSS standard est presque certainement la meilleure réponse.
John Haugeland
13
@JohnHaugeland, la meilleure réponse lors de l'utilisation du framework React est la réponse acceptée, allant dans tout le style React, qui a des fonctions de nettoyage que dans certains cas vous devez faire. Ce n'est pas une bonne pratique d'avoir des composants cachés dans le noir. Si vous mélangez des trucs, vous feriez mieux de devenir natif, ce qui est toujours plus rapide qu'autre chose.
Claudiu Hojda
4
Non, ce n'est vraiment pas le cas. Utiliser react pour réinventer CSS est une mauvaise idée.
John Haugeland
8
En outre, vous semblez avoir complètement raté le point de ce que j'ai dit, qui était d'utiliser CSS pour masquer et afficher l'élément, plutôt que d'utiliser React pour le supprimer physiquement. Vous pouvez utiliser React pour utiliser CSS pour masquer et afficher l'élément tout aussi facilement: <div style = {{display: this.props.example}} />.
John Haugeland
5
@ClaudiuHojda avoir des composants cachés dans le noir est en fait une très bonne pratique dans certains cas, je pense à une navigation réactive, où vous avez besoin que les liens restent dans le HTML même s'ils sont cachés avec css
Toni Leigh

Réponses:

546

Réagissez vers 2020

Dans le onClickrappel, appelez la fonction setter du hook d'état pour mettre à jour l'état et restituer:

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

React vers 2014

La clé consiste à mettre à jour l'état du composant dans le gestionnaire de clics à l'aide de setState. Lorsque les changements d'état sont appliqués, la renderméthode 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'));
<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

Douglas
la source
3
Oui, bon point sur l'état vs les accessoires. Une meilleure façon de le faire serait comme dans le tutoriel ici, où la barre de recherche et le tableau des résultats sont des frères et sœurs au lieu de mettre les résultats dans la recherche: facebook.github.io/react/docs/thinking-in-react.html
Douglas
53
Comme indiqué dans l'autre réponse, l'insertion / suppression est beaucoup plus lente que le masquage de classe simple.
John Haugeland
4
Je pense que les commentaires de John doivent être revus. Je suis allé avec la réponse voulue et c'était soigné et je me sentais plus comme réagir. Cependant, je n'ai pas pu définir les états initiaux et rien d'utile sur un composant non monté. J'envisage d'utiliser css pour masquer les choses à la place. Les auditeurs sur les composants non montés échoueront silencieusement, ce qui m'a causé une grande perte de temps aujourd'hui.
atterri le
Cela signifie-t-il que react restituera le composant lorsque le style change (est réglé pour afficher / masquer)!?
alex
@Douglas, sauf si je l'ai manqué, de cette façon ne permet pas de revenir à l'original. Je suppose que le PO ne l'a peut-être pas voulu, mais comment puis-je l'inclure?
Le ver du
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>
John Haugeland
la source
12
Il vaut mieux renvoyer conditionnellement null comme dans la réponse de Douglas. Cela permet à React de le supprimer entièrement du DOM. Dans votre cas, le div et son contenu sont toujours dans le DOM ne sont tout simplement pas affichés. Cela peut avoir des implications sur les performances.
pmont
125
Les implications en termes de performances sont bien pires pour l'ajout et la suppression d'un élément dom que pour le masquage et l'affichage. Je suis conscient de la différence entre son approche et la mienne, et je pense que vous vous trompez exactement. Veuillez envisager de prendre le temps de définir les "implications en termes de performances", puis de les mesurer.
John Haugeland
6
"Les reflows sont garantis avec ajout / suppression" - Pas avec des éléments absolument positionnés, c'est ainsi que Famous obtient ses performances incroyables. Mais vous faites un point valable sur les mesures.
pmont
9
pour ce que ça vaut, cela est mentionné dans les documents de réaction ici: facebook.github.io/react/docs/…
Brad Parks
85
J'ai donc simplement testé le retour de null par rapport à la définition d'une classe cachée avec 161 nœuds dom assez grands. Il est beaucoup plus rapide d'utiliser une classe que de supprimer le nœud.
Jonathan Rowny
121

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

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

est équivalent à:

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

Lean pourquoi


Également une syntaxe alternative avec display: 'none';

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

Cependant, si vous en abusez display: 'none', cela conduit à une pollution DOM et ralentit finalement votre application.

Lyubomir
la source
Attention! Utilisez l'approche «double esperluette (&&)» uniquement pour les valeurs booléennes. {this.state.myComponents.length && <MyComponent />} affichera 0 si le tableau vide de myComponents (par exemple)
Mega Proger
57

Voici mon approche.

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

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

{opened && <SomeElement />}

Cela ne sera rendu SomeElementque si openedc'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 (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

Raisons d'utiliser cette approche au lieu de CSS 'display: none';

  • Bien qu'il puisse être «moins cher» de masquer un élément avec CSS - dans ce cas, l'élément «caché» est toujours «vivant» dans le monde réactif (ce qui pourrait le rendre plus cher)
    • cela signifie que si les accessoires de l'élément parent (par exemple. <TabView> ) changeront - même si vous ne voyez qu'un seul onglet, les 5 onglets seront tous rendus
    • l'élément caché peut encore avoir certaines méthodes de cycle de vie en cours d'exécution - par exemple. il peut récupérer certaines données du serveur après chaque mise à jour même si elles ne sont pas visibles
    • l'élément caché peut planter l'application si elle reçoit des données incorrectes. Cela peut arriver car vous pouvez «oublier» les nœuds invisibles lors de la mise à jour de l'état
    • vous pouvez par erreur définir un mauvais style d'affichage lorsque vous rendez l'élément visible - par exemple. certains div est 'display: flex' par défaut, mais vous définirez 'display: block' par erreur avecdisplay: invisible ? 'block' : 'none' ce qui pourrait casser la mise en page
    • l'utilisation someBoolean && <SomeNode />est très simple à comprendre et à raisonner, surtout si votre logique liée à l'affichage de quelque chose ou non devient complexe
    • dans de nombreux cas, vous souhaitez «réinitialiser» l'état de l'élément lorsqu'il réapparaît. par exemple. vous pouvez avoir un curseur que vous souhaitez mettre en position initiale chaque fois qu'il est affiché. (si c'est le comportement souhaité pour conserver l'état de l'élément précédent, même s'il est caché, ce qui est rare, j'imaginerais utiliser CSS si se souvenir de cet état d'une manière différente serait compliqué)
pie6k
la source
2
Ceci est un excellent exemple! Une petite chose, boxContent devrait être className = "boxContent"
Bhetzie
5
Il y a un bug ici: this.setState({isOpened: !isOpened});. Ne dépendez pas de l'état lui-même lorsque vous modifiez l'état. Voici un bon exemple: reactjs.org/docs/… Il devrait donc en être ainsi this.setState( s => ({isOpened: !s.isOpened}) ). Notez la fonction de flèche dans setState.
arcol
Avez-vous une source / un benchmark / un exemple confirmant ceci "Si vous définissez display: aucun - l'élément est toujours rendu par react et ajouté au DOM - qui peut avoir un impact négatif sur les performances." ?
neiya
@neiya non. CSS peut être plus performant avec de petits éléments, mais très souvent, vous voulez rendre éventuellement de grandes parties de contenu, par exemple. languette. De plus, bien qu'un élément soit caché avec CSS - il est toujours vivant dans le monde de React. Cela signifie qu'il pourrait mettre à jour son état, récupérer des données, etc., ce qui pourrait être coûteux et entraîner un comportement inattendu. Et c'est l'OMI en fait très simple à mettre en œuvre.
pie6k
17

avec la dernière version react 0.11, vous pouvez également simplement retourner null pour ne pas avoir de contenu rendu.

Rendu à null

squiddle
la source
11

J'ai créé un petit composant qui gère cela pour vous: react-toggle-display

Il définit l'attribut style sur la display: none !importantbase du hideou des showaccessoires.

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);
ccnokes
la source
10

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 trébucher. Je vais donc passer en revue les trois principales méthodes (plus une option hors sujet) pour le faire et expliquer les avantages et les inconvénients. J'écris principalement cela parce que l'option 1 a été beaucoup recommandée et qu'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 n'allez rendre le composant qu'une seule fois et le laisser là. Le problème est qu'il provoquera la réaction de 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 cela, vous remarquerez que le constructeur est appelé à chaque clic sur le 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, rendu, etc. est cher, cela ralentira considérablement l'affichage du composant. Cela signifie également que vous ne pouvez pas l'utiliser avec des composants avec état où vous souhaitez que l'état soit préservé lorsqu'il est masqué (et restauré lorsqu'il est affiché.) Le seul avantage est que le composant caché n'est pas créé du tout tant qu'il n'est pas sélectionné. Les composants cachés ne retarderont donc pas le chargement initial de votre page. Il peut également y avoir des cas où vous VOULEZ réinitialiser un composant avec état lorsqu'il est basculé. Dans ce cas, c'est votre meilleure option.

Option 2: Rendu conditionnel chez l'enfant

Cela crée les deux composants une fois. Puis court-circuite le reste du code de rendu si le composant est masqué. Vous pouvez également court-circuiter d'autres logiques dans d'autres méthodes à l'aide de l'hélice visible. Remarquez le fichier console.log dans la page 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')
);

Maintenant, si la logique d'initialisation est rapide et que les enfants sont sans état, vous ne verrez aucune différence de performances ou de fonctionnalités. Cependant, pourquoi faire en sorte que React crée 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 sur un composant, ce qui ralentira la page lors du basculement. L'option 2 exécutera tous les inits du composant lors du chargement de la première page. Ralentir cette première charge. Faut noter à nouveau. Si vous ne montrez le composant qu'une seule fois en fonction d'une condition et ne le changez pas, ou si vous souhaitez qu'il se réinitialise lors du basculement, l'option 1 est correcte et probablement la meilleure option.

Si le chargement lent des pages pose problème, cela signifie que vous avez du code coûteux dans une méthode de cycle de vie et ce n'est généralement pas une bonne idée. Vous pouvez, et devriez probablement, résoudre le lent chargement des pages en retirant le code coûteux des méthodes de cycle de vie. Déplacez-le vers une fonction asynchrone lancée par ComponentDidMount et demandez au rappel de le placer dans une variable d'état avec setState (). Si la variable d'état est nulle et que le composant est visible, la fonction de rendu renvoie un espace réservé. Sinon, restituez les données. De cette façon, la page se chargera rapidement et remplira les onglets lors de leur chargement. Vous pouvez également déplacer la logique dans le parent et envoyer les résultats aux enfants comme accessoires. De cette façon, vous pouvez prioriser les onglets qui seront chargés en premier. Ou mettez en cache les résultats et exécutez la logique uniquement 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 venez de créer une classe CSS avec display: none et attribuez la classe en fonction de prop. L'inconvénient est que le code entier de chaque composant caché est appelé et que 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 masqué et supprime complètement le composant du DOM.) Il semble que cela soit plus rapide pour 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 changez les accessoires. Ou peut-être aucun 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 masquer des composants, mais il pourrait être une meilleure solution pour certains cas d'utilisation que de masquer. Disons que vous avez des 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 des 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 celui qui est actif.

Kelnor
la source
9

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

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

Exemple ici

Utilisation des crochets 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>
  )
}

Exemple ici

daniloprates
la source
J'aime cette réponse maigre. Dommage que le violon ne courrait pas.
Juan Lanus
Comme mentionné dans une réponse précédente, vous ne devez pas dépendre de l'état dansthis.setState() .
Dan Dascalescu
8

Vous définissez une valeur booléenne dans l'état (par exemple, «show»), puis effectuez:

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

return <div style={style}>...</div>
Brigand
la source
J'ai essayé ceci, mais l'événement de clic n'a pas commuté le CSS au bloc d'affichage. Je ne sais pas exactement comment l'accomplir. Des conseils supplémentaires?
user1725382
1
Cela implique d'apporter des modifications actives à la table de règles de style. Il est préférable d'avoir une seule règle existante que vous pouvez activer et désactiver, qui ne fait pas partie des propriétés dynamiques du nœud dom.
John Haugeland
1
Ce n'est pas grave si vous utilisez une classe ou un style ici ... vous semblez très travaillé à ce sujet.
Brigand
2
L'utilisation d'une classe est plus rapide de quelques ordres de grandeur. C'est bon à savoir.
Jason Rice
1
Pourrait simplement utiliser des noms de classe conditionnels avec: github.com/JedWatson/classnames
backdesk
7

La meilleure pratique est ci-dessous selon la documentation:

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

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

Dynamique
la source
Cette réponse a déjà été donnée un an plus tôt, il est donc correct de la supprimer maintenant.
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>
     );
  }
}
sgr
la source
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>
        );
      }
  }
Akanksha gore
la source
4

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

Dans React, vous pouvez créer des composants distincts qui encapsulent le comportement dont vous avez besoin. Ensuite, vous ne pouvez rendre que certains d'entre eux, selon l'état de votre application.

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

Vous devez essentiellement montrer le composant lorsque le bouton est cliqué, vous pouvez le faire de deux manières, en utilisant Pure React ou en utilisant CSS, en utilisant Pure React, vous pouvez faire quelque chose comme le code ci-dessous dans votre cas, donc lors de la première exécution, les résultats ne sont pas affichés comme hideResultsest true, mais en cliquant sur le bouton, le changement va de l' Etat et hideResultsest falseet le get composant rendu à nouveau avec les nouvelles conditions de valeur, ceci est une utilisation très courante de changer vue des composants dans 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);

Si vous souhaitez approfondir le rendu conditionnel dans React, jetez un œil ici .

Alireza
la source
1
cela devrait être la manière la plus élégante!
cinquième
4

Exemple de masquage / affichage simple avec React Hooks: (essayez de ne pas jouer de violon)

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;
StefanBob
la source
2
il peut être plus simple de simplement {montrer? 1: 2}
Piotr Żak
3

Si vous souhaitez voir comment faire basculer l'affichage d'un composant à la caisse de 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'));
Nicholas Porter
la source
3

Une méthode simple pour afficher / masquer des éléments dans React à l'aide de crochets

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

Maintenant, ajoutons un peu de logique à notre méthode de rendu:

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

Et

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

Bon travail.

super
la source
2

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

Créez 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}  />;
    }
};

Étendez votre propre composant:

export const MyComp= HidableComponent(MyCompBasic);

Ensuite, vous pouvez l'utiliser comme ceci:

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

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

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

vinga
la source
1

Utiliser le module 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>
        );
    }
}
qinyuanbin
la source
1

Utiliser ref et manipuler CSS

Une façon pourrait être d'utiliser React refet de manipuler la classe CSS à l'aide de l'API du navigateur. Son avantage est d'éviter de restituer dans React si le seul but est de masquer / afficher certains éléments DOM en cliquant sur un bouton.

// 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 Corrigez-moi si je me trompe. :)

UtkarshPramodGupta
la source
Exemple de codesandbox.io créé, ici: utgzx.csb.app , le code est à codesandbox.io/embed/react-show-hide-with-css-utgzx
PatS
0

Si vous utilisez bootstrap 4, vous pouvez masquer l'élément de cette façon

className={this.state.hideElement ? "invisible" : "visible"}
ThomasP1988
la source
0

Cela peut également être réalisé comme ceci (moyen très simple)

 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
  }
   );
     }
basitmir
la source
Veuillez lire la définition de "l'état basé sur l'état précédent" sur reactjs.org/docs/react-component.html#setstate . Ce serait également bien de corriger l'indentation à la fin.
Dan Dascalescu
0

cet exemple montre comment vous pouvez basculer entre les composants en utilisant une bascule qui bascule après chaque 1 seconde

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);
Snivio
la source
Qu'est-ce que l'URL de l'image bizarre? Vous pouvez utiliser un service d'espace réservé d'image standard comme placeimg.com
Dan Dascalescu
0

Utilisez cette syntaxe allégée et courte:

{ this.state.show && <MyCustomComponent /> }
Zain Ul Hassan
la source
Peut-être pourriez-vous développer votre syntaxe allégée et courte pour expliquer comment cela fonctionne. Oh, attendez, cela a été fait dans une réponse 3 ans plus tôt . Qu'apporte à nouveau votre réponse?
Dan Dascalescu
0

Voici la solution simple, efficace et la meilleure avec un composant React sans classe pour afficher / masquer les éléments. Utilisation de React-Hooks qui est disponible dans le dernier projet create-react-app qui utilise 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 :)

Remi Prasanna
la source
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;
}
Naved Khan
la source
-1

Vous pouvez utiliser le fichier css

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

et dans le fichier css

    .search-results {
     ...
     display: none
     &.show {
      display: block
   }
}
arco
la source
-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);
Alan Paul Mathew
la source
1
Pouvez-vous expliquer ce que vous avez fait et pourquoi est-ce mieux que la réponse acceptée?
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>
    );
  }
}
Mohammad Golkar
la source
Pouvez-vous ajouter des explications pour une meilleure compréhension? Merci!
Shanteshwar Inde
@ShanteshwarInde: cela reproduit la même idée d'une réponse précédente , y compris une utilisation incorrecte de setState en fonction de l'état actuel. Voir reactjs.org/docs/react-component.html#setstate : "Si vous devez définir l'état en fonction de l'état précédent, lisez l'argument de mise à jour".
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>

Venka
la source
4
Bien que ce code puisse répondre à la question, fournir un contexte supplémentaire concernant pourquoi et / ou comment ce code répond à la question améliore sa valeur à long terme.
xiawi
Ce que @xiawi a dit. Veuillez également utiliser à la constplace de varlorsque vous déclarez des constantes.
Dan Dascalescu