Mostrar u ocultar elemento en React

688

Estoy jugando con React.js por primera vez y no puedo encontrar una manera de mostrar u ocultar algo en una página a través del evento de clic. No estoy cargando ninguna otra biblioteca en la página, por lo que estoy buscando una forma nativa de usar la biblioteca React. Esto es lo que tengo hasta ahora. Me gustaría mostrar los resultados div cuando se activa el evento de clic.

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);
7
  • 12
    El comentario aceptado utiliza tecnología novedosa para hacer lo que la tecnología existente a nivel nativo puede hacer de manera más fácil, rápida y compartible con otros lenguajes y bibliotecas. Manejar esto con CSS estándar es casi con certeza la mejor respuesta. 30 de enero de 2015 a las 0:43
  • 13
    @JohnHaugeland, la mejor respuesta cuando se usa el framework React es la respuesta aceptada, yendo todo al estilo React, que tiene funciones de limpieza que en algunos casos debes hacer. No es una buena práctica tener componentes escondidos en la oscuridad. Si mezcla cosas, es mejor que sea todo nativo, que siempre es más rápido que cualquier otra cosa. 27 de mayo de 2015 a las 12:06
  • 6
    No, realmente no lo es. Usar react para reinventar CSS es una mala idea. 29 de mayo de 2015 a las 18:08
  • 9
    Además, parece que no entendiste por completo lo que dije, que era usar CSS para ocultar y mostrar el elemento, en lugar de usar React para eliminarlo físicamente. Usted puede utilizar Reaccionar con el uso de CSS para ocultar y mostrar el elemento con la misma facilidad: <div style = {{display: this.props.example}} />. 29 de mayo de 2015 a las 18:09
  • 6
    @ClaudiuHojda tener componentes ocultos en la oscuridad es en realidad una muy buena práctica en algunos casos, estoy pensando en una navegación receptiva, donde necesita que los enlaces permanezcan en el HTML incluso si están ocultos con css 3 de diciembre de 2015 a las 7:50
719

Reaccionar alrededor de 2020

En la onClickdevolución de llamada, llame a la función de establecimiento del gancho de estado para actualizar el estado y volver a renderizar:

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

Reaccionar alrededor de 2014

La clave es actualizar el estado del componente en el controlador de clic usando setState. Cuando se aplican los cambios de estado, renderse vuelve a llamar al método con el nuevo estado:

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

13
  • 4
    Sí, buen punto sobre el estado frente a los accesorios. Una mejor manera de hacer esto sería como en el tutorial aquí, donde la barra de búsqueda y la tabla de resultados son hermanos en lugar de poner Resultados dentro de Búsqueda: facebook.github.io/react/docs/thinking-in-react.html
    Douglas
    2 de julio de 2014 a las 15:58
  • 62
    Como se señaló en la otra respuesta, la inserción / eliminación son mucho más lentas que el simple enmascaramiento de clases. 30 de enero de 2015 a las 0:42
  • 6
    Creo que los comentarios de Johns necesitan ser revisados. Fui con la respuesta pretendida y fue ordenada y 'sentí' más reaccionar. Sin embargo, no pude establecer estados iniciales ni nada útil en un componente desmontado. Estoy buscando usar css para ocultar cosas en su lugar. Los oyentes en componentes desmontados fallarán silenciosamente, esto me ha causado una gran pérdida de tiempo hoy.
    landed
    25 de febrero de 2016 a las 12:25
  • 2
    ¿Eso significa que react volverá a renderizar el componente cuando el estilo cambie (está configurado para mostrar / ocultar)?
    alex
    9 de noviembre de 2016 a las 6:55
  • 4
    En lugar de { showResults ? <Results /> : null }poder hacer{ showResults && <Results /> }
    zwbetz
    16 nov.20 a las 15:38
264
<style type="text/css">
    .hidden { display:none; }
</style>
const Example = props => 
  <div className={props.shouldHide? 'hidden' : undefined}>Hello</div>
13
  • 15
    Es mejor devolver nulo condicionalmente como en la respuesta de Douglas. Eso permite a React eliminarlo del DOM por completo. En su caso, el div y su contenido todavía están en el DOM simplemente no se muestran. Esto puede tener implicaciones en el rendimiento.
    pmont
    7 de septiembre de 2014 a las 3:31
  • 151
    Las implicaciones de rendimiento son mucho peores para agregar y eliminar un elemento dom que para ocultarlo y mostrarlo. Soy consciente de la diferencia entre su enfoque y el mío, y creo que usted tiene esto exactamente mal. Considere tomarse el tiempo para definir "implicaciones en el desempeño" y luego medirlo. 7 de septiembre de 2014 a las 4:41
  • 6
    "Los reflujos están garantizados con agregar / quitar" - No con elementos absolutamente posicionados, que es como Famous obtiene su increíble rendimiento. Pero haces un punto válido sobre las métricas.
    pmont
    8 de septiembre de 2014 a las 2:02
  • 10
    por lo que vale, esto se menciona en los documentos de reacción aquí: facebook.github.io/react/docs/… 25 de septiembre de 2014 a las 9:45
  • 100
    Así que solo probé devolver nulo frente a configurar una clase oculta con 161 nodos dom bastante grandes. Es significativamente más rápido usar una clase que eliminar el nodo. 29/01/15 a las 23:15
157

Aquí hay una sintaxis alternativa para el operador ternario:

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

es equivalente a:

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

saber por que


También sintaxis alternativa con display: 'none';

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

Sin embargo, si hace un uso excesivo display: 'none', esto conduce a la contaminación del DOM y, en última instancia, ralentiza su aplicación.

4
  • 4
    ¡Advertencia! Utilice el enfoque 'doble ampersand (&&)' solo para valores bool. {this.state.myComponents.length && <MyComponent />} representará 0, si myComponents matriz vacía (por ejemplo) 22 mar.20 a las 12:36
  • 1
    @MegaProger en tal caso, se convierte en booleano con !!ie{ !!this.state.myComponents.length && <MyComponent /> }
    Pawel
    18 de ene a las 15:13
  • Esto no es en ningún sentido una "sintaxis alternativa para el operador ternario". Esto tiene errores, y hay otros lugares además de la doble negación de la cláusula de apertura donde esto causará problemas. 9 de abril a las 14:38
  • El segundo ejemplo es un olor a código, en mi opinión
    Alex W
    26 abr a las 18:20
81

Este es mi enfoque.

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

En el código anterior, para lograr esto, estoy usando un código como:

{opened && <SomeElement />}

Eso se rendirá SomeElementsolo si openedes cierto. Funciona debido a la forma en que JavaScript resuelve las condiciones lógicas:

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 = [];
someValue.length && <SomeElement /> // will output 0, which will be rednered by react
// it'll be better to:
someValue.length > 0 && <SomeElement /> // will render nothing as we cast the value to boolean

Razones para usar este enfoque en lugar de CSS 'display: none';

  • Si bien podría ser 'más barato' ocultar un elemento con CSS, en tal caso, el elemento 'oculto' todavía está 'vivo' en el mundo de reacción (lo que podría hacerlo mucho más caro)
    • significa que si los accesorios del elemento principal (p. ej. <TabView>) cambiarán, incluso si solo ve una pestaña, las 5 pestañas se volverán a representar
    • el elemento oculto aún puede tener algunos métodos de ciclo de vida en ejecución, por ejemplo. podría recuperar algunos datos del servidor después de cada actualización, incluso aunque no sea visible
    • el elemento oculto podría bloquear la aplicación si recibe datos incorrectos. Puede suceder ya que puede 'olvidarse' de los nodos invisibles al actualizar el estado
    • por error, podría establecer un estilo de 'visualización' incorrecto al hacer visible el elemento, por ejemplo. algún div es 'display: flex' de forma predeterminada, pero establecerá 'display: block' por error con lo display: invisible ? 'block' : 'none'que podría romper el diseño
    • usar someBoolean && <SomeNode />es muy simple de entender y razonar, especialmente si su lógica relacionada con mostrar algo o no se vuelve compleja
    • en muchos casos, desea 'restablecer' el estado del elemento cuando reaparece. p.ej. es posible que tenga un control deslizante que desee establecer en la posición inicial cada vez que se muestre. (si ese es el comportamiento deseado para mantener el estado del elemento anterior, incluso si está oculto, lo cual en mi opinión es raro; de hecho, consideraría usar CSS si recordar este estado de una manera diferente sería complicado)
4
  • 2
    ¡Este es un gran ejemplo! Una pequeña cosa, boxContent debe ser className = "boxContent"
    Bhetzie
    21/11/2017 a las 2:31
  • 7
    Hay un error aquí: this.setState({isOpened: !isOpened});. No dependa del estado en sí, cuando modifique el estado. Aquí es un ejemplo bueno: reactjs.org/docs/... lo que debe ser: this.setState( s => ({isOpened: !s.isOpened}) ). Tenga en cuenta la función de flecha dentro de setState.
    arcol
    28/12/18 a las 10:55
  • ¿Tiene alguna fuente / punto de referencia / ejemplo que confirme esto "Si configura display: none - el elemento aún se representa mediante react y se agrega a DOM - que puede tener un impacto negativo en el rendimiento". ?
    neiya
    4 feb.20 a las 13:34
  • @neiya no lo hago. CSS puede ser más eficaz con elementos pequeños, pero a menudo desea representar opcionalmente grandes partes del contenido, por ejemplo. pestaña. Además, aunque algún elemento está oculto con CSS, todavía está vivo en el mundo react. Significa que puede actualizar su estado, recuperar algunos datos, etc., lo que puede ser costoso y provocar un comportamiento inesperado. Y en mi opinión, es muy sencillo de implementar. 9 abr.20 a las 19:21
18

con la versión más reciente, react 0.11, también puede devolver nulo para que no se muestre el contenido.

Renderizado a nulo

13

Esta es una buena forma de hacer uso del DOM virtual :

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

Ejemplo aquí

Usando ganchos de 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>
  )
}

Ejemplo aquí

3
11

Creé un pequeño componente que maneja esto por ti: react-toggle-display

Establece el atributo de estilo en display: none !importantfunción de los accesorios hideo show.

Uso de ejemplo:

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

Ya hay varias respuestas excelentes, pero no creo que se hayan explicado muy bien y varios de los métodos dados contienen algunas trampas que pueden hacer tropezar a la gente. Así que voy a repasar las tres formas principales (más una opción fuera del tema) para hacer esto y explicar los pros y los contras. Principalmente estoy escribiendo esto porque la Opción 1 se recomendó mucho y hay muchos problemas potenciales con esa opción si no se usa correctamente.

Opción 1: Representación condicional en el padre.

No me gusta este método a menos que solo renderice el componente una vez y lo deje ahí. El problema es que hará que reaccione para crear el componente desde cero cada vez que cambie la visibilidad. Este es el ejemplo. LogoutButton o LoginButton se representan condicionalmente en el LoginControl principal. Si ejecuta esto, notará que se llama al constructor con cada clic de botón. 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')
);

Ahora React es bastante rápido para crear componentes desde cero. Sin embargo, todavía tiene que llamar a su código al crearlo. Entonces, si su código de constructor, componentDidMount, render, etc. es costoso, entonces se ralentizará significativamente la visualización del componente. También significa que no puede usar esto con componentes con estado en los que desea que el estado se conserve cuando se oculte (y se restaure cuando se muestre). La única ventaja es que el componente oculto no se crea en absoluto hasta que se selecciona. Por lo tanto, los componentes ocultos no retrasarán la carga de su página inicial. También puede haber casos en los que DESEA que un componente con estado se restablezca cuando se alterna. En cuyo caso esta es tu mejor opción.

Opción 2: representación condicional en el niño

Esto crea ambos componentes una vez. Luego, cortocircuita el resto del código de renderizado si el componente está oculto. También puede cortocircuitar otra lógica en otros métodos utilizando el accesorio visible. Observe el archivo console.log en la página del 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')
);

Ahora, si la lógica de inicialización es rápida y los hijos no tienen estado, no verá una diferencia en el rendimiento o la funcionalidad. Sin embargo, ¿por qué hacer que React cree un componente completamente nuevo en cada alternancia de todos modos? Sin embargo, si la inicialización es costosa, la Opción 1 la ejecutará cada vez que cambie un componente, lo que ralentizará la página al cambiar. La opción 2 ejecutará todos los inits del componente en la carga de la primera página. Disminuir la velocidad de esa primera carga. Debería anotar de nuevo. Si solo muestra el componente una vez en función de una condición y no lo alterna, o si desea que se restablezca cuando se alterna, entonces la Opción 1 está bien y probablemente la mejor opción.

Sin embargo, si la carga lenta de la página es un problema, significa que tiene un código costoso en un método de ciclo de vida y, por lo general, no es una buena idea. Puede, y probablemente debería, resolver la carga lenta de la página sacando el costoso código de los métodos del ciclo de vida. Muévalo a una función asíncrona iniciada por ComponentDidMount y haga que la devolución de llamada lo coloque en una variable de estado con setState (). Si la variable de estado es nula y el componente es visible, haga que la función de renderizado devuelva un marcador de posición. De lo contrario, renderice los datos. De esa forma, la página se cargará rápidamente y llenará las pestañas a medida que se cargan. También puede mover la lógica al padre y enviar los resultados a los hijos como accesorios. De esa manera, puede priorizar qué pestañas se cargan primero. O almacenar en caché los resultados y ejecutar la lógica solo la primera vez que se muestra un componente.

Opción 3: Ocultación de clases

La ocultación de clases es probablemente la más fácil de implementar. Como se mencionó, solo crea una clase CSS con display: none y asigna la clase según prop. La desventaja es que se llama al código completo de cada componente oculto y todos los componentes ocultos se adjuntan al DOM. (La Opción 1 no crea los componentes ocultos en absoluto. Y la Opción 2 cortocircuita el código innecesario cuando el componente está oculto y elimina el componente del DOM por completo). Parece que esto es más rápido para alternar la visibilidad según algunas pruebas realizadas por los comentaristas en otras respuestas, pero no puedo hablar de eso.

Opción 4: Un componente pero cambiar Props. O tal vez ningún componente y HTML en caché.

Este no funcionará para todas las aplicaciones y está fuera de tema porque no se trata de ocultar componentes, pero podría ser una mejor solución para algunos casos de uso que ocultar. Digamos que tienes pestañas. Podría ser posible escribir un componente React y simplemente usar los accesorios para cambiar lo que se muestra en la pestaña. También puede guardar el JSX para indicar variables y usar un accesorio para decidir qué JSX devolver en la función de renderizado. Si el JSX debe generarse, hágalo y almacénelo en el archivo principal y envíe el correcto como accesorio. O genere en el niño y almacénelo en el estado del niño y use accesorios para seleccionar el activo.

9

Establece un valor booleano en el estado (por ejemplo, 'mostrar)' y luego:

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

return <div style={style}>...</div>
5
  • Intenté esto, pero el evento de clic no cambió el CSS para mostrar el bloque. No sé exactamente cómo lograrlo. ¿Algún consejo adicional? 1 de julio de 2014 a las 18:16
  • 1
    Esto implica realizar cambios activos en la tabla de reglas de estilo. Es mucho mejor tener una sola regla existente que pueda activar y desactivar, que no forma parte de las propiedades dinámicas del nodo dom. 30/01/15 a las 19:20
  • 1
    Realmente no importa si usas una clase o estilo aquí ... pareces muy preocupado por esto.
    Brigand
    1 feb 2015 a las 9:39
  • 2
    Usar una clase es más rápido en un par de órdenes de magnitud. Es bueno saberlo. 03/03/15 a las 21:13
  • 1
    Podría usar nombres de clases condicionales con: github.com/JedWatson/classnames 30/11/15 a las 16:20
6

Las mejores prácticas se encuentran a continuación de acuerdo con la documentación:

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

Renderice el elemento solo cuando el estado sea válido.

1
  • 1
    Esta respuesta ya se dio un año antes, por lo que está bien eliminarla ahora. 25/10/19 a las 8:56
6

Un método simple para mostrar / ocultar elementos en React usando Hooks

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

Ahora, agreguemos algo de lógica a nuestro método de renderizado:

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

Y

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

Buen trabajo.

1
  • ¡Este es el mejor!
    Deborah
    15 oct.20 a las 0:42
6

Ejemplo simple de ocultar / mostrar con React Hooks: (srry sobre no violín)

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

Empiezo con esta declaración del equipo de React:

In React, you can create distinct components that encapsulate behaviour you need. Then, you can render only some of them, depending on the state of your application.

Conditional rendering in React works the same way conditions work in JavaScript. Use JavaScript operators like if or the conditional operator to create elements representing the current state, and let React update the UI to match them.

Básicamente, necesita mostrar el componente cuando se hace clic en el botón, puede hacerlo de dos maneras, usando React puro o usando CSS, usando el modo React puro, puede hacer algo como el siguiente código en su caso, por lo que en la primera ejecución, los resultados no se muestra como hideResultses true, pero haciendo clic en el botón, el cambio va a estado y hideResultses falsey el componente get rendido de nuevo con las nuevas condiciones de valor, esto es muy común el uso de cambiar en vista de componentes Reaccionar ...

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 desea realizar más estudios sobre la representación condicional en React, eche un vistazo aquí .

1
  • 1
    ¡Esta debería ser la forma más elegante!
    fifth
    17 de abril de 2019 a las 3:16
2

En algunos casos, el componente de orden superior puede ser útil:

Cree un componente de orden superior:

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

Amplíe su propio componente:

export const MyComp= HidableComponent(MyCompBasic);

Entonces puedes usarlo así:

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

Esto reduce un poco la repetición y hace cumplir las convenciones de nomenclatura, sin embargo, tenga en cuenta que MyComp aún se instanciará; la forma de omitir se mencionó anteriormente:

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

2

Si desea ver cómo CAMBIAR la visualización de un componente, consulte este violín.

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

Use ref and manipulate CSS

Una forma podría ser usar React refy manipular la clase CSS usando la API del navegador. Su beneficio es evitar volver a renderizar en React si el único propósito es ocultar / mostrar algún elemento DOM con solo hacer clic en un botón.

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

PD Corrígeme si me equivoco. :)

3
  • Ejemplo creado de codesandbox.io, aquí: utgzx.csb.app , el código está en codesandbox.io/embed/react-show-hide-with-css-utgzx
    PatS
    21/08/19 a las 16:57
  • Si bien definitivamente funcionaría, se considera un anti-patrón manipular el DOM a menos que no tenga la opción, por ejemplo, al integrar una biblioteca de terceros incompatible, como un antiguo widget de jQuery, etc. 5 de julio a las 21:34
  • 1
    Tienes toda la razón @EmileBergeron. Es una de las formas no optimizadas de hacerlo cuando no está dispuesto a introducir State en el componente. Escribí la respuesta 2 años atrás cuando todavía era un novato en React. 7 de julio a las 5:24
2

Pude usar la propiedad css "oculta". No conozco posibles inconvenientes.

export default function App() {
    const [hidden, setHidden] = useState(false);
    return (
      <div>
        <button onClick={() => setHidden(!hidden)}>HIDE</button>
        <div hidden={hidden}>hidden component</div>
      </div>
    );
  }
1

Si usa bootstrap 4, puede ocultar el elemento de esa manera

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

Utilice el módulo 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

Aquí viene la mejor solución simple, efectiva y con un componente de reacción sin clase para mostrar / ocultar los elementos. Uso de React-Hooks que está disponible en el último proyecto create-react-app que usa 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;

Codificación feliz :)

0

Esto también se puede lograr así (de manera muy fácil)

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

este ejemplo muestra cómo puede cambiar entre componentes mediante el uso de un interruptor que cambia después de cada 1 segundo

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);
1
  • ¿Qué pasa con la URL de la imagen extraña? Puede utilizar un servicio de marcador de posición de imagen estándar como placeimg.com 25/10/19 a las 9:04
0

Utilice esta sintaxis ajustada y corta:

{ this.state.show && <MyCustomComponent /> }
1
  • 1
    Tal vez podría ampliar su sintaxis ajustada y corta para explicar cómo funciona. Oh, espera, eso se hizo en una respuesta 3 años antes . ¿Qué trae tu respuesta a la mesa de nuevo? 25/10/19 a las 9:02
0

Simplemente descubra una forma nueva y mágica con el uso de (useReducer) para componentes funcionales

const [estado, handleChangeState] = useReducer ((estado) =>! estado, falso); cambian de estado

-1
// Try this way

class App extends Component{

  state = {
     isActive:false
  }

  showHandler = ()=>{
      this.setState({
          isActive: true
      })
  }

  hideHandler = () =>{
      this.setState({
          isActive: false
      })
  }

   render(){
       return(
           <div>
           {this.state.isActive ? <h1>Hello React jS</h1> : null }
             <button onClick={this.showHandler}>Show</button>
             <button onClick={this.hideHandler}>Hide</button>
           </div>
       )
   }
}
-1
//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;
}


<button onClick={()=>this.setState({yourState: !this.props.yourState}>Toggle View</button>
-2
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
  • 2
    ¿Puede explicar lo que hizo y por qué es mejor que la respuesta aceptada?
    Seblor
    20 de mayo de 2019 a las 14:42
-2
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>
    );
  }
}
2