Mostrar ou ocultar o elemento no React

532

Estou brincando com o React.js pela primeira vez e não consigo encontrar uma maneira de mostrar ou ocultar algo em uma página via evento click. Como não estou carregando nenhuma outra biblioteca para a página, estou procurando uma maneira nativa usando a biblioteca React. É isso que eu tenho até agora. Gostaria de mostrar a div de resultados quando o evento click for acionado.

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
fonte
11
O comentário aceito usa uma nova tecnologia para fazer o que a tecnologia existente no nível nativo pode fazer de maneira mais fácil, rápida e compartilhada com outros idiomas e bibliotecas. Lidar com isso com CSS padrão é quase certamente a melhor resposta.
precisa saber é o seguinte
13
@JohnHaugeland, a melhor resposta ao usar a estrutura React é a resposta aceita, seguindo todo o estilo React, que possui funções de limpeza que, em alguns casos, você deve fazer. Não é uma boa prática ter componentes apenas escondidos no escuro. Se você misturar coisas, é melhor ficar nativo, sempre mais rápido do que qualquer outra coisa.
Claudiu Hojda
4
Não, não é mesmo. Usar o react para reinventar o CSS é uma má ideia.
John Haugeland
8
Além disso, você parece ter esquecido completamente o que eu disse, que era usar CSS para ocultar e mostrar o elemento, em vez de usar o React para removê-lo fisicamente. Você pode usar o React para usar o CSS para ocultar e mostrar o elemento com a mesma facilidade: <div style = {{display: this.props.example}} />.
John Haugeland
5
@ClaudiuHojda ter componentes ocultos no escuro é realmente uma prática muito boa em alguns casos, estou pensando em navegação responsiva, onde você precisa que os links permaneçam no HTML, mesmo se estiverem ocultos com css
Toni Leigh

Respostas:

545

Reagir por volta de 2020

No onClickretorno de chamada, chame a função setter do gancho de estado para atualizar o estado e renderizar novamente:

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

Reagir por volta de 2014

A chave é atualizar o estado do componente no manipulador de cliques usando setState. Quando as alterações de estado são aplicadas, o rendermétodo é chamado novamente com o novo 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
fonte
3
Sim, bom argumento sobre estado versus adereços. Uma maneira melhor de fazer isso é como no tutorial aqui, onde a barra de pesquisa e a tabela de resultados são irmãos em vez de colocar Resultados dentro da Pesquisa: facebook.github.io/react/docs/thinking-in-react.html
Douglas
53
Conforme observado na outra resposta, a inserção / exclusão é muito mais lenta que o simples mascaramento de classe.
precisa saber é o seguinte
4
Acho que os comentários de Johns precisam ser revistos. Eu fui com a resposta pretendida e isso foi legal e 'senti' mais como reagir. No entanto, não consegui definir estados iniciais e nada de útil em um componente desmontado. Eu estou olhando para usar css para esconder as coisas. Ouvintes em componentes desmontados falharão silenciosamente, o que me causou grande perda de tempo hoje.
desembarcou
Isso significa que o react reapresentará o componente quando o estilo mudar (está definido para mostrar / ocultar)!?
alex
@ Douglas, a menos que eu tenha perdido, dessa maneira não é possível voltar ao original. Acho que o OP pode não ter desejado, mas como posso incluir isso?
O worm
221
<style type="text/css">
    .hidden { display:none; }
</style>
render: function() {
    return (
      <div className={this.props.shouldHide ? 'hidden' : ''}>
        This will be hidden if you set <tt>props.shouldHide</tt> 
        to something truthy.
      </div>
    );
}

// or in more modern JS and stateless react
const Example = props => <div className={props.shouldHide}/>Hello</div>
John Haugeland
fonte
12
É melhor retornar nulo condicionalmente, como na resposta de Douglas. Isso permite que o React o remova totalmente do DOM. No seu caso, a div e seu conteúdo ainda estão no DOM simplesmente não sendo exibidos. Isso pode ter implicações no desempenho.
pmont
125
As implicações de desempenho são muito piores para adicionar e remover um elemento dom do que para ocultá-lo e mostrá-lo. Estou ciente da diferença entre a abordagem dele e a minha, e acredito que você entenda isso exatamente errado. Por favor, considere reservar um tempo para definir "implicações de desempenho" e depois medi-lo.
John Haugeland
6
"Os refluxos são garantidos com adição / remoção" - Não com elementos absolutamente posicionados, e é assim que o Famous obtém seu desempenho incrível. Mas você faz uma observação válida sobre as métricas.
pmont
9
pelo que vale a pena, isso é mencionado nos documentos de reação aqui: facebook.github.io/react/docs/…
Brad Parks
85
Então, acabei de testar retornando null vs. definindo uma classe oculta com 161 nós de domínio razoavelmente grandes. É significativamente mais rápido usando uma classe do que remover o nó.
precisa saber é o seguinte
120

Aqui está uma sintaxe alternativa para o operador ternário:

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

é equivalente a:

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

Magra porque


Também sintaxe alternativa com display: 'none';

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

No entanto, se você usar demais display: 'none', isso leva à poluição do DOM e, finalmente, diminui a velocidade do seu aplicativo.

Lyubomir
fonte
Atenção! Use a abordagem 'e comercial duplo (&&)' apenas para valores bool. {this.state.myComponents.length && <MyComponent />} renderizará 0, se myComponents estiver vazio (por exemplo)
Mega Proger
57

Aqui está a minha abordagem.

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

No código acima, para conseguir isso, estou usando um código como:

{opened && <SomeElement />}

Isso renderizará SomeElementapenas se openedfor verdadeiro. Funciona devido à maneira como o JavaScript resolve as condições 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

Razões para usar essa abordagem em vez de CSS 'display: none';

  • Embora possa ser "mais barato" ocultar um elemento com CSS - nesse caso, o elemento "oculto" ainda está "vivo" no mundo de reação (o que pode torná-lo realmente muito mais caro)
    • significa que, se os objetos do elemento pai (por exemplo <TabView>) forem alterados - mesmo que você veja apenas uma guia, todas as 5 guias serão renderizadas novamente
    • o elemento oculto ainda pode ter alguns métodos de ciclo de vida em execução - por exemplo. pode buscar alguns dados do servidor após cada atualização, mesmo que não seja visível
    • o elemento oculto pode travar o aplicativo se ele receber dados incorretos. Isso pode acontecer, pois você pode 'esquecer' os nós invisíveis ao atualizar o estado
    • você pode, por engano, definir o estilo de 'exibição' errado ao tornar o elemento visível - por exemplo. alguma div é 'display: flex' por padrão, mas você definirá 'display: block' por engano, com o display: invisible ? 'block' : 'none'que pode quebrar o layout
    • usar someBoolean && <SomeNode />é muito simples de entender e raciocinar, especialmente se sua lógica relacionada à exibição de algo ou não se torna complexa
    • em muitos casos, você deseja 'redefinir' o estado do elemento quando ele reaparecer. por exemplo. você pode ter um controle deslizante que deseja definir para a posição inicial toda vez que for exibido. (se esse é o comportamento desejado para manter o estado anterior do elemento, mesmo se estiver oculto, qual IMO é raro - eu consideraria o uso de CSS se lembrar desse estado de uma maneira diferente seria complicado)
pie6k
fonte
2
Este é um excelente exemplo! Uma coisa pequena, boxContent deve ser className = "boxContent"
Bhetzie
5
Há um bug aqui: this.setState({isOpened: !isOpened});. Não dependa do próprio estado, quando você modifica o estado. Aqui está um bom exemplo: reactjs.org/docs/... Assim deve ser: this.setState( s => ({isOpened: !s.isOpened}) ). Observe a função de seta dentro de setState.
ARCOL
Você tem alguma fonte / benchmark / exemplo que confirme isso "Se você definir a exibição: nenhum elemento ainda será renderizado por reagir e adicionado ao DOM - que pode ter um impacto ruim no desempenho." ?
neiya 04/02
@neiya eu não. O CSS pode ter mais desempenho com pequenos elementos, mas muitas vezes você deseja renderizar opcionalmente grandes partes do conteúdo, por exemplo. aba. Além disso, enquanto algum elemento está oculto com CSS - ele ainda está vivo no mundo da reação. Isso significa que ele pode atualizar seu estado, buscar alguns dados, etc., que podem ser caros e levar a um comportamento inesperado. E é realmente muito simples de implementar na IMO.
pie6k 9/04
17

com a versão mais recente react 0.11, você também pode retornar nulo para que nenhum conteúdo seja renderizado.

Renderizando para null

squiddle
fonte
11

Eu criei um pequeno componente que lida com isso para você: react-toggle-display

Ele define o atributo de estilo como display: none !importantbaseado em hideou showprops.

Exemplo 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
fonte
10

Já existem várias ótimas respostas, mas não acho que tenham sido explicadas muito bem e vários dos métodos fornecidos contêm algumas dicas que podem enganar as pessoas. Então, vou abordar as três principais maneiras (mais uma opção fora do tópico) para fazer isso e explicar os prós e os contras. Estou escrevendo principalmente porque a Opção 1 foi muito recomendada e há muitos problemas em potencial com essa opção, se não for usada corretamente.

Opção 1: renderização condicional no pai.

Não gosto desse método, a menos que você só renderize o componente uma vez e o deixe lá. O problema é que isso fará com que o reagir crie o componente do zero toda vez que você alternar a visibilidade. Aqui está o exemplo. LogoutButton ou LoginButton estão sendo renderizados condicionalmente no LoginControl pai. Se você executar isso, notará que o construtor está sendo chamado a cada clique do botão. 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')
);

Agora, o React é muito rápido na criação de componentes a partir do zero. No entanto, ele ainda precisa chamar seu código ao criá-lo. Portanto, se seu código de construtor, componentDidMount, render, etc for caro, diminuirá significativamente a exibição do componente. Isso também significa que você não pode usá-lo com componentes com estado em que deseja que o estado seja preservado quando oculto (e restaurado quando exibido.) A única vantagem é que o componente oculto não é criado, até que seja selecionado. Portanto, componentes ocultos não atrasarão o carregamento da sua página inicial. Também pode haver casos em que você QUER que um componente com estado seja redefinido quando alternado. Nesse caso, esta é sua melhor opção.

Opção 2: renderização condicional no filho

Isso cria os dois componentes uma vez. Em seguida, provoque um curto-circuito no restante do código de renderização se o componente estiver oculto. Você também pode causar um curto-circuito em outras lógicas em outros métodos usando o suporte visível. Observe o console.log na página 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')
);

Agora, se a lógica de inicialização for rápida e os filhos estiverem sem estado, você não verá uma diferença no desempenho ou na funcionalidade. No entanto, por que fazer o React criar um novo componente a cada alternância? Se a inicialização for cara, a Opção 1 a executará toda vez que você alternar um componente que diminuirá a velocidade da página ao alternar. A opção 2 executará todas as entradas do componente no carregamento da primeira página. Abrandando a primeira carga. Deve notar novamente. Se você está apenas mostrando o componente uma vez com base em uma condição e não o está alternando, ou deseja que seja redefinido quando alternado, a opção 1 é boa e provavelmente a melhor opção.

Se o carregamento lento da página for um problema, significa que você tem um código caro em um método de ciclo de vida e isso geralmente não é uma boa ideia. Você pode, e provavelmente deveria, resolver o carregamento lento da página movendo o código caro dos métodos do ciclo de vida. Mova-o para uma função assíncrona iniciada por ComponentDidMount e faça com que o retorno de chamada o coloque em uma variável de estado com setState (). Se a variável state for nula e o componente estiver visível, faça com que a função render retorne um espaço reservado. Caso contrário, renderize os dados. Dessa forma, a página será carregada rapidamente e preencherá as guias à medida que forem carregadas. Você também pode mover a lógica para o pai e enviar os resultados aos filhos como acessórios. Dessa forma, você pode priorizar quais guias serão carregadas primeiro. Ou armazene em cache os resultados e execute a lógica apenas na primeira vez que um componente é mostrado.

Opção 3: ocultação de classe

Ocultar classes é provavelmente o mais fácil de implementar. Como mencionado, você acabou de criar uma classe CSS com display: none e atribuir a classe com base em prop. A desvantagem é que todo o código de cada componente oculto é chamado e todos os componentes ocultos são anexados ao DOM. (A opção 1 não cria os componentes ocultos. A opção 2 provoca um curto-circuito no código desnecessário quando o componente está oculto e remove o componente do DOM completamente.) Parece que é mais rápido alternar a visibilidade de acordo com alguns testes feitos por comentaristas. outras respostas, mas não posso falar com isso.

Opção 4: Um componente, mas altere Adereços. Ou talvez nenhum componente e cache de HTML.

Este não funcionará para todos os aplicativos e está fora de tópico porque não se trata de ocultar componentes, mas pode ser uma solução melhor para alguns casos de uso do que ocultar. Digamos que você tenha abas. Pode ser possível escrever um React Component e apenas usar os acessórios para alterar o que é exibido na guia. Você também pode salvar o JSX nas variáveis ​​de estado e usar um suporte para decidir qual JSX retornar na função de renderização. Se o JSX precisar ser gerado, faça-o, armazene-o em cache no pai e envie o correto como suporte. Ou gere no filho e armazene em cache no estado do filho e use adereços para selecionar o ativo.

Kelnor
fonte
9

Esta é uma boa maneira de fazer uso do 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>
     );
  }
}

Exemplo aqui

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

Exemplo aqui

daniloprates
fonte
Eu gosto dessa resposta enxuta. Pena que o violino não funcionaria.
Juan Lanus
Como mencionado em uma resposta anterior, você nãothis.setState() deve depender do estado .
Dan Dascalescu 25/10/19
8

Você define um valor booleano no estado (por exemplo, 'show)' e depois faz:

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

return <div style={style}>...</div>
Brigand
fonte
Eu tentei isso, mas o evento click não mudou o css para exibir o bloco. Estou perdido exatamente em como fazê-lo. Alguma dica adicional?
user1725382
1
Isso envolve fazer alterações ativas na tabela de regras de estilo. É muito melhor ter uma única regra existente que você possa ativar e desativar, que não faz parte das propriedades dinâmicas do nó dom.
John Haugeland
1
Realmente não importa se você usa uma classe ou estilo aqui ... você parece muito preocupado com isso.
Brigand
2
Usar uma classe é mais rápido em algumas ordens de magnitude. É bom saber.
Jason Arroz
1
Poderia apenas usar nomes de classe condicionais com: github.com/JedWatson/classnames
backdesk
7

As práticas recomendadas estão abaixo de acordo com a documentação:

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

Renderize o elemento somente quando o estado for válido.

Dinâmico
fonte
Essa resposta já foi dada um ano antes, então não há problema em excluí-la agora.
Dan Dascalescu 25/10/19
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
fonte
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
fonte
4

Começo com esta declaração da equipe React:

No React, você pode criar componentes distintos que encapsulam o comportamento necessário. Em seguida, você pode renderizar apenas alguns deles, dependendo do estado do seu aplicativo.

A renderização condicional no React funciona da mesma maneira que as condições funcionam no JavaScript. Use operadores JavaScript como if ou o operador condicional para criar elementos que representam o estado atual e deixe o React atualizar a interface do usuário para correspondê-los.

Você basicamente precisa mostrar o componente quando o botão é clicado, você pode fazê-lo de duas maneiras, usando o React puro ou o CSS, usando o React puro, você pode fazer algo como o código abaixo no seu caso, portanto, na primeira execução, resultados não está mostrando como hideResultsestá true, mas clicando no botão, o estado mudará e hideResultsestá falsee o componente será renderizado novamente com as novas condições de valor, esse é um uso muito comum da alteração da exibição do componente no React ...

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

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

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

});

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

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

Se você quiser estudar mais sobre renderização condicional no React, dê uma olhada aqui .

Alireza
fonte
1
essa deve ser a maneira mais elegante!
quinto
4

Exemplo simples de ocultar / mostrar com React Hooks: (srry about no fiddle)

const Example = () => {

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

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

};

export default Example;
StefanBob
fonte
2
pode ser mais simples mostrar {show? 1: 2}
Piotr Żak 15/01
3

Se você gostaria de ver como alternar a exibição de um componente, confira este violino.

http://jsfiddle.net/mnoster/kb3gN/16387/

var Search = React.createClass({
    getInitialState: function() {
        return { 
            shouldHide:false
        };
    },
    onClick: function() {
        console.log("onclick");
        if(!this.state.shouldHide){
            this.setState({
                shouldHide: true 
            })
        }else{
                    this.setState({
                shouldHide: false 
            })
        }
    },
render: function() {
    return (
      <div>
        <button onClick={this.onClick}>click me</button>
        <p className={this.state.shouldHide ? 'hidden' : ''} >yoyoyoyoyo</p>
      </div>
    );
}
});

ReactDOM.render( <Search /> , document.getElementById('container'));
Nicholas Porter
fonte
3

Um método simples para mostrar / ocultar elementos no React usando Hooks

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

Agora, vamos adicionar alguma lógica ao nosso método de renderização:

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

E

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

Bom trabalho.

superup
fonte
2

Em alguns casos, o componente de ordem superior pode ser útil:

Crie um componente de ordem 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}  />;
    }
};

Estenda seu próprio componente:

export const MyComp= HidableComponent(MyCompBasic);

Então você pode usá-lo assim:

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

Isso reduz um pouco de clichê e impõe aderência às convenções de nomenclatura; no entanto, lembre-se de que o MyComp ainda será instanciado - a maneira de omitir foi mencionada anteriormente:

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

vinga
fonte
1

Use o 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
fonte
1

Use ref e manipule CSS

Uma maneira poderia ser usar o React refe manipular a classe CSS usando a API do navegador. Seu benefício é evitar a renderização novamente no React se o único objetivo é ocultar / mostrar algum elemento DOM com o clique de um botão.

// 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 Corrija-me se estiver errado. :)

UtkarshPramodGupta
fonte
Exemplo de codesandbox.io criado, aqui: utgzx.csb.app , o código está em codesandbox.io/embed/react-show-hide-hide-with-css-utgzx
PatS
0

Se você usar o bootstrap 4, poderá ocultar o elemento dessa maneira

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

Isso também pode ser alcançado assim (maneira muito 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
fonte
Leia sobre a configuração "estado com base no estado anterior" em reactjs.org/docs/react-component.html#setstate . Além disso, seria bom corrigir o recuo no final.
Dan Dascalescu 25/10/19
0

este exemplo mostra como você pode alternar entre componentes usando uma alternância que alterna após 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
fonte
O que há com o URL da imagem estranha? Você pode usar um serviço de espaço reservado para imagem padrão, como placeimg.com
Dan Dascalescu 25/10/19
0

Use esta sintaxe enxuta e curta:

{ this.state.show && <MyCustomComponent /> }
Zain Ul Hassan
fonte
Talvez você possa expandir sua sintaxe enxuta e curta para explicar como funciona. Oh, espere, isso foi feito em uma resposta três anos antes . O que sua resposta traz para a mesa novamente?
Dan Dascalescu 25/10/19
0

Aí vem a solução simples, eficaz e melhor com um Componente de reação sem classe para mostrar / ocultar os elementos. Uso de React-Hooks, disponível no projeto create-react-app mais recente que usa o 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
fonte
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
fonte
-1

Você pode usar o arquivo css

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

e no arquivo css

    .search-results {
     ...
     display: none
     &.show {
      display: block
   }
}
arco
fonte
-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
fonte
1
Você pode explicar o que fez e por que é melhor que a resposta aceita?
Seblor 20/05/19
-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
fonte
Você pode adicionar explicações para uma melhor compreensão? Obrigado!
Shanteshwar Inde 11/09/19
@ ShanteshwarInde: isso duplica a mesma ideia de uma resposta anterior , incluindo o uso incorreto de setState, dependendo do estado atual. Consulte reactjs.org/docs/react-component.html#setstate : "Se você precisar definir o estado com base no estado anterior, leia sobre o argumento do atualizador".
Dan Dascalescu 25/10/19
-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
fonte
4
Embora esse código possa responder à pergunta, fornecer um contexto adicional a respeito de por que e / ou como esse código responde à pergunta melhora seu valor a longo prazo.
xiawi 19/09/19
O que @xiawi disse. Além disso, use em constvez de varquando declarar constantes.
Dan Dascalescu 25/10/19