Mostrar u ocultar elemento en Reaccionar

532

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

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

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

React.renderComponent(<Search /> , document.body);
usuario1725382
fuente
11
El comentario aceptado utiliza tecnología novedosa para hacer lo que la tecnología existente en el nivel nativo puede hacer de manera más fácil, más rápida y compartible con otros idiomas y bibliotecas. Manejar esto con CSS estándar es casi seguro la mejor respuesta.
John Haugeland
13
@JohnHaugeland, la mejor respuesta cuando se usa React Framework es la respuesta aceptada, con todo el 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 mezclas cosas, es mejor que seas nativo, lo que siempre es más rápido que cualquier otra cosa.
Claudiu Hojda
44
No, realmente no lo es. Usar reaccionar para reinventar CSS es una mala idea.
John Haugeland
8
Además, parece haber perdido completamente el punto de 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}} />.
John Haugeland
55
@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 necesitas que los enlaces permanezcan en el HTML incluso si están ocultos con css
Toni Leigh

Respuestas:

545

Reaccionar hacia 2020

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

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

Reacciona alrededor de 2014

La clave es actualizar el estado del componente en el controlador de clics mediante setState. Cuando se aplican los cambios de estado, renderse llama nuevamente 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

Douglas
fuente
3
Sí, buen punto sobre estado vs accesorios. Una mejor manera de hacerlo sería en el tutorial aquí, donde la barra de búsqueda y la tabla de resultados son hermanos en lugar de poner los resultados dentro de la búsqueda: facebook.github.io/react/docs/thinking-in-react.html
Douglas
53
Como se señaló en la otra respuesta, la inserción / eliminación es mucho más lenta que el simple enmascaramiento de clases.
John Haugeland
44
Creo que los comentarios de Johns deben revisarse. Fui con la respuesta deseada y eso fue ordenado y 'sentí' que reaccionaría más. Sin embargo, no pude establecer estados iniciales y nada útil en un componente desmontado. Estoy mirando el uso de 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.
aterrizó
¿Eso significa que reaccionar volverá a generar el componente cuando cambie el estilo (está configurado para mostrar / ocultar)?
alex
@Douglas, a menos que me lo haya perdido, de esta manera no se permite volver al original. Supongo que el OP puede no haberlo querido, pero ¿cómo puedo incluir esto?
El gusano
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
fuente
12
Es mejor devolver condicionalmente nulo como en la respuesta de Douglas. Eso permite que React lo elimine por completo del DOM. En su caso, el div y sus contenidos todavía están en el DOM simplemente no se muestran. Esto puede tener implicaciones de rendimiento.
pmont
125
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 tienes esto exactamente equivocado. Considere tomarse el tiempo para definir "implicaciones de rendimiento" y luego medirlo.
John Haugeland
66
"Los reflujos están garantizados con agregar / quitar": no con elementos posicionados absolutamente, así es como Famous obtiene su increíble rendimiento. Pero haces un punto válido en las métricas.
pmont
99
por lo que vale, esto se menciona en los documentos de reacción aquí: facebook.github.io/react/docs/…
Brad Parks
85
Así que acabo de probar devolver nulo frente a establecer una clase oculta con 161 nodos dom bastante grandes. Es significativamente más rápido usar una clase que eliminar el nodo.
Jonathan Rowny
120

Aquí hay una sintaxis alternativa para el operador ternario:

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

es equivalente a:

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

Inclinarse por qué


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

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

Sin embargo, si usa en exceso display: 'none', esto conduce a la contaminación DOM y, en última instancia, ralentiza su aplicación.

Lyubomir
fuente
¡Advertencia! Utilice el enfoque de 'doble ampersand (&&)' solo para valores bool. {this.state.myComponents.length && <MyComponent />} representará 0, si myComponents está vacío (por ejemplo)
Mega Proger
57

Aquí está 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 código como:

{opened && <SomeElement />}

Eso 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 = 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

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

  • Si bien puede ser 'más barato' ocultar un elemento con CSS, en ese caso, el elemento 'oculto' todavía está 'vivo' en el mundo de reacción (lo que podría hacer que sea mucho más caro)
    • significa que si <TabView>cambian los accesorios del elemento padre (p. ej. ), incluso si solo ve una pestaña, las 5 pestañas se volverán a representar
    • el elemento oculto aún podría tener algunos métodos de ciclo de vida en ejecución, por ejemplo. puede obtener algunos datos del servidor después de cada actualización, incluso si no es 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, puede establecer un estilo de 'visualización' incorrecto al hacer visible el elemento, por ejemplo. algunos div son 'display: flex' por defecto, pero configurará 'display: block' por error, lo display: invisible ? 'block' : 'none'que podría romper el diseño
    • el uso 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 vuelve a aparecer. 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 que es raro en la OMI; de hecho, consideraría usar CSS si recordar este estado de una manera diferente sería complicado)
pie6k
fuente
2
¡Este es un gran ejemplo! Una pequeña cosa, boxContent debería ser className = "boxContent"
Bhetzie
55
Hay un error aquí: this.setState({isOpened: !isOpened});. No dependa del estado en sí mismo 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
¿Tiene alguna fuente / punto de referencia / ejemplo que confirme esto "Si configura display: none, el elemento aún se procesa al reaccionar y se agrega a DOM, lo que puede tener un impacto negativo en el rendimiento". ?
Neiya
@neiya no lo hago. CSS puede ser más eficiente con elementos pequeños, pero a menudo desea representar opcionalmente grandes partes de contenido, por ejemplo. lengüeta. Además, si bien algún elemento está oculto con CSS, todavía está vivo en el mundo de reacción. Significa que podría actualizar su estado, obtener algunos datos, etc., lo que podría ser costoso y conducir a un comportamiento inesperado. Y es IMO en realidad muy simple de implementar.
pie6k
17

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

Renderizado a nulo

calamar
fuente
11

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

Establece el atributo de estilo display: none !importantsegún los accesorios hideo show.

Ejemplo de uso:

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
fuente
10

Ya hay varias respuestas excelentes, pero no creo que se hayan explicado muy bien y varios de los métodos proporcionados contienen algunas trampas que podrían hacer tropezar a las personas. 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 escribo 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 vayas a representar el componente una vez y lo dejes allí. El problema es que hará que reaccione para crear el componente desde cero cada vez que cambie la visibilidad. Aquí está el ejemplo. LogoutButton o LoginButton se representan condicionalmente en el LoginControl primario. Si ejecuta esto, notará que se llama al constructor con cada clic en el 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 el código de su constructor, componentDidMount, render, etc. es costoso, entonces se ralentizará significativamente mostrando el componente. También significa que no puede usar esto con componentes con estado donde desea que se conserve el estado cuando está oculto (y restaurado cuando se muestra). La única ventaja es que el componente oculto no se crea hasta que se selecciona. Por lo tanto, los componentes ocultos no retrasarán la carga de la página inicial. También puede haber casos en los que DESEA un componente con estado para restablecer 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 usando el accesorio visible. Observe el archivo console.log en la página de 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, entonces no verá una diferencia en el rendimiento o la funcionalidad. Sin embargo, ¿por qué hacer que React cree un componente nuevo cada vez que se alterna? Sin embargo, si la inicialización es costosa, la Opción 1 la ejecutará cada vez que active un componente 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. Retrasando esa primera carga. Debe tener en cuenta de nuevo. Si solo muestra el componente una vez en función de una condición y no lo alterna, o desea que se restablezca cuando se activa, entonces la Opción 1 está bien y probablemente sea 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 que generalmente no es una buena idea. Puede, y probablemente debería, resolver la carga lenta de la página moviendo 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 la ponga 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 representación devuelva un marcador de posición. De lo contrario, renderice los datos. De esa manera, 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 niños como accesorios. De esa manera, puede priorizar qué pestañas se cargan primero. O guarde en caché los resultados y solo ejecute la lógica la primera vez que se muestre un componente.

Opción 3: Ocultar clase

La ocultación de clases es probablemente la más fácil de implementar. Como se mencionó, simplemente crea una clase CSS con display: none y asigna la clase en función del accesorio. La desventaja es que se llama el código completo de cada componente oculto y todos los componentes ocultos están conectados al DOM. (La opción 1 no crea los componentes ocultos en absoluto. Y la opción 2 corta 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 al 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 los accesorios. O tal vez ningún componente en absoluto y caché HTML.

Esta 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 la ocultación. Digamos que tienes pestañas. Es 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 en variables de estado y usar un accesorio para decidir qué JSX devolver en la función de representación. Si se debe generar el JSX, hágalo y almacénelo en caché en el padre 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.

Kelnor
fuente
9

Esta es una buena manera 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 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í

daniloprates
fuente
Me gusta esta respuesta magra. Lástima que el violín no corriera.
Juan Lanus
Como se mencionó en una respuesta anterior, no debe depender del estado enthis.setState() .
Dan Dascalescu
8

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

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

return <div style={style}>...</div>
Bandido
fuente
Intenté esto, pero el evento click no cambió el CSS para mostrar el bloque. Estoy perdido exactamente sobre cómo lograrlo. ¿Algún consejo adicional?
user1725382
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 es parte de las propiedades dinámicas del nodo dom.
John Haugeland
1
Realmente no importa si usas una clase o un estilo aquí ... parece que estás muy preocupado por esto.
Brigante
2
Usar una clase es más rápido en un par de órdenes de magnitud. Es bueno saberlo.
Jason Rice
1
Podría usar nombres de clase condicionales con: github.com/JedWatson/classnames
backdesk
7

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

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

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

Dinámica
fuente
Esta respuesta ya se dio un año antes, por lo que está bien eliminarla ahora.
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
fuente
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
fuente
4

Comienzo con esta declaración del equipo React:

En React, puede crear componentes distintos que encapsulan el comportamiento que necesita. Luego, puede renderizar solo algunos de ellos, dependiendo del estado de su aplicación.

La representación condicional en React funciona de la misma manera que las condiciones en JavaScript. Use operadores de JavaScript como if o el operador condicional para crear elementos que representen el estado actual y deje que React actualice la IU para que coincida con ellos.

Básicamente, debe mostrar el componente cuando se hace clic en el botón, puede hacerlo de dos maneras, usando React puro o usando CSS, usando la forma React pura, puede hacer algo como el siguiente código en su caso, por lo que en la primera ejecución, los resultados no se muestran como hideResultses true, pero al hacer clic en el botón, el estado cambiará y hideResultses falsey el componente se renderizará nuevamente con las nuevas condiciones de valor, este es un uso muy común de cambiar la vista de componentes en 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 desea seguir estudiando en representación condicional en React, eche un vistazo aquí .

Alireza
fuente
1
¡Esta debería ser la forma más elegante!
quinto
4

Ejemplo simple de ocultar / mostrar con React Hooks: (pregunta por no tocar el 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;
StefanBob
fuente
2
puede ser más simple simplemente {mostrar? 1: 2}
Piotr Żak
3

Si desea ver cómo alternar la visualización de un componente, compruebe 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'));
Nicholas Porter
fuente
3

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

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.

superup
fuente
2

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

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

Extienda su propio componente:

export const MyComp= HidableComponent(MyCompBasic);

Entonces puedes usarlo así:

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

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

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

vinga
fuente
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>
        );
    }
}
qinyuanbin
fuente
1

Usa ref y manipula CSS

Una forma podría ser usar React refy manipular la clase CSS utilizando la API del navegador. Su beneficio es evitar volver a reproducir 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. :)

UtkarshPramodGupta
fuente
Ejemplo de codesandbox.io creado, aquí: utgzx.csb.app , el código está en codesandbox.io/embed/react-show-hide-with-css-utgzx
PatS
0

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

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

Esto también se puede lograr de esta manera (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
  }
   );
     }
Basitmir
fuente
Lea sobre la configuración del "estado basado en el estado anterior" en reactjs.org/docs/react-component.html#setstate . Además, sería bueno arreglar la sangría al final.
Dan Dascalescu
0

Este ejemplo muestra cómo puede cambiar entre componentes mediante el uso de una palanca que cambia 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);
Snivio
fuente
¿Qué pasa con la URL de imagen extraña? Puede utilizar un servicio de marcador de posición de imagen estándar como placeimg.com
Dan Dascalescu
0

Use esta sintaxis simple y corta:

{ this.state.show && <MyCustomComponent /> }
Zain Ul Hassan
fuente
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 nuevamente?
Dan Dascalescu
0

Aquí viene la solución simple, efectiva y mejor 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;

Happy Coding :)

Remi Prasanna
fuente
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
fuente
-1

Puedes usar el archivo css

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

y en el archivo css

    .search-results {
     ...
     display: none
     &.show {
      display: block
   }
}
arco
fuente
-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
fuente
1
¿Puedes explicar lo que hiciste y por qué es mejor que la respuesta aceptada?
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
fuente
¿Puede agregar una explicación para una mejor comprensión? ¡Gracias!
Shanteshwar Inde
@ShanteshwarInde: esto duplica la misma idea de una respuesta anterior , incluido el uso incorrecto de setState según el estado actual. Consulte reactjs.org/docs/react-component.html#setstate : "Si necesita establecer el estado en función del estado anterior, lea sobre el argumento del actualizador".
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
fuente
44
Si bien este código puede responder la pregunta, proporcionar un contexto adicional con respecto a por qué y / o cómo responde la pregunta mejora su valor a largo plazo.
xiawi
Lo que dijo @xiawi. Además, utilice en constlugar de varcuando declara constantes.
Dan Dascalescu