Показать или скрыть элемент в React

532

Я возиться с React.js в первый раз и не могу найти способ показать или скрыть что-то на странице с помощью события клика. Я не загружаю никакую другую библиотеку на страницу, поэтому я ищу какой-то собственный способ использования библиотеки React. Это то, что я до сих пор. Я хотел бы показать результаты div, когда срабатывает событие 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);
user1725382
источник
11
В принятом комментарии используется новая технология, чтобы сделать то, что существующие технологии на нативном уровне могут сделать проще, быстрее и совместно с другими языками и библиотеками. Обработка этого со стандартным CSS почти наверняка лучший ответ.
Джон Хаугеланд
13
@JohnHaugeland, лучший ответ при использовании React Framework - это принятый ответ, охватывающий весь стиль React, который имеет функции очистки, которые в некоторых случаях вы должны выполнять. Это не очень хорошая практика, когда компоненты просто прячутся в темноте. Если вы смешиваете что-то, вам лучше стать полностью нативным, что всегда быстрее, чем все остальное.
Клавдиу Хойда
4
Нет, это действительно не так. Использование реакции для переизобретения CSS - плохая идея.
Джон Хаугеланд
8
Кроме того, вы, похоже, полностью упустили из виду то, что я сказал, а именно использование CSS для скрытия и отображения элемента, а не использование React для его физического удаления. Вы можете использовать React, чтобы с помощью CSS скрыть и показать элемент так же легко: <div style = {{display: this.props.example}} />.
Джон Хаугеланд
5
@ClaudiuHojda с компонентами, скрывающими в темноте, в некоторых случаях является очень хорошей практикой, я имею в виду адаптивную навигацию, где вам нужны ссылки, чтобы оставаться в HTML, даже если они скрыты с помощью css
Тони Ли,

Ответы:

546

Реакция около 2020 года

В onClickобратном вызове позвоните государственном крюке функции сеттера для обновления состояния и повторной визуализация:

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

Реакция около 2014

Ключ должен обновить состояние компонента в обработчике кликов, используя setState. Когда изменения состояния применяются, renderметод вызывается снова с новым состоянием:

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

Дуглас
источник
3
Да, хороший момент о состоянии против реквизита. Лучший способ сделать это, как в учебном пособии, где строка поиска и таблица результатов - это братья и сестры, а не помещать результаты в поиск: facebook.github.io/react/docs/thinking-in-react.html
Douglas
53
Как отмечено в другом ответе, вставка / удаление намного медленнее, чем простая маскировка классов.
Джон Хаугеланд
4
Я думаю, что комментарии Джонс нуждается в рассмотрении. Я пошел с намеченным ответом, и он был аккуратным и «чувствовал» больше реагировать как Однако я не смог установить начальные состояния и что-нибудь полезное для неустановленного компонента. Я смотрю на использование CSS, чтобы скрыть вещи. Слушатели на отключенных компонентах будут молча терпеть неудачу, это вызвало у меня большую потерю времени сегодня.
приземлился
Означает ли это, что реакция перезапустит компонент при изменении стиля (установлен на показ / скрытие)!?
Алекс
@ Дуглас, если я не пропустил его, этот способ не позволяет вернуться к оригиналу. Я думаю, что ОП, возможно, не хотел этого, но как я могу включить это?
Червь
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>
Джон Хаугеланд
источник
12
Лучше условно вернуть ноль, как в ответе Дугласа. Это позволяет React полностью удалить его из DOM. В вашем случае div и его содержимое все еще находятся в DOM, но не отображаются. Это может повлиять на производительность.
14:00
125
Влияние на производительность гораздо хуже для добавления и удаления элемента dom, чем для его скрытия и показа. Я осознаю разницу между его подходом и моим, и я считаю, что вы абсолютно не правы. Пожалуйста, подумайте о том, чтобы найти время, чтобы определить «последствия для производительности», а затем измерить его.
Джон Хаугеланд,
6
«Перефразирование гарантировано с добавлением / удалением» - не с абсолютно позиционированными элементами, как Famous получает свою невероятную производительность. Но вы делаете правильную точку на метриках.
Пмонт
9
что бы это ни стоило, это упомянуто в реактивных документах здесь: facebook.github.io/react/docs/…
Брэд Паркс,
85
Итак, я только что протестировал возврат нулевого значения против установки скрытого класса с 161 довольно большим dom-узлом. Использование класса значительно быстрее, чем удаление узла.
Джонатан Ровни
121

Вот альтернативный синтаксис для троичного оператора:

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

эквивалентно:

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

Почему


Также альтернативный синтаксис с display: 'none';

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

Однако, если вы злоупотребляете display: 'none', это приводит к загрязнению DOM и в конечном итоге замедляет работу вашего приложения.

Любомир
источник
Предупреждение! Используйте подход «двойной амперсанд (&&)» только для значений bool. {this.state.myComponents.length && <MyComponent />} будет отображать 0, если myComponents пустой массив (например)
Mega Proger
57

Вот мой подход.

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

В приведенном выше коде, чтобы достичь этого, я использую такой код:

{opened && <SomeElement />}

Это будет отображаться, SomeElementтолько если openedэто правда. Это работает из-за способа, которым JavaScript разрешает логические условия:

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

Причины использования этого подхода вместо CSS «display: none»;

  • Хотя может быть «дешевле» скрыть элемент с помощью CSS - в таком случае «скрытый» элемент все еще «жив» в реагирующем мире (что может сделать его на самом деле более дорогим)
    • это означает, что если реквизиты родительского элемента (например, <TabView>) изменится - даже если вы видите только одну вкладку, все 5 вкладок будут перерисованы
    • скрытый элемент может все еще иметь запущенные методы жизненного цикла - например. после каждого обновления он может получать некоторые данные с сервера, даже если он не виден
    • скрытый элемент может вызвать сбой приложения, если оно получит неверные данные. Это может произойти, так как вы можете «забыть» о невидимых узлах при обновлении состояния
    • Вы можете по ошибке установить неправильный стиль отображения при отображении элемента, например. некоторый div это «display: flex» по умолчанию, но вы по ошибке установите «display: block», display: invisible ? 'block' : 'none'что может нарушить компоновку
    • использовать someBoolean && <SomeNode />очень просто для понимания и рассуждений, особенно если ваша логика, связанная с отображением чего-либо или нет, становится сложной
    • во многих случаях вы хотите «сбросить» состояние элемента при его повторном появлении. например. у вас может быть слайдер, который вы хотите установить в исходное положение каждый раз, когда он отображается. (если это желаемое поведение, чтобы сохранить предыдущее состояние элемента, даже если оно скрыто, что IMO встречается редко - я бы действительно подумал об использовании CSS, если запоминание этого состояния по-другому было бы сложно)
pie6k
источник
2
Это отличный пример! Одна небольшая вещь, boxContent должно быть className = "boxContent"
Bhetzie
5
Существует ошибка здесь: this.setState({isOpened: !isOpened});. Не зависит от самого государства, когда вы изменяете состояние. Вот хороший пример: reactjs.org/docs/... Так оно и должно быть: this.setState( s => ({isOpened: !s.isOpened}) ). Обратите внимание на функцию стрелки внутри setState.
Arcol
Есть ли у вас источник / тест / пример, подтверждающий это: «Если вы установите display: none - элемент по-прежнему визуализируется по реакции и добавляется в DOM - это может оказать плохое влияние на производительность». ?
neiya
@neiya я не знаю. CSS может быть более производительным с небольшими элементами, но довольно часто вы хотите визуализировать необязательно большие части контента, например. Вкладка. Кроме того, хотя какой-то элемент скрыт с помощью CSS - он все еще жив в мире реакции. Это означает, что он может обновить свое состояние, получить некоторые данные и т. Д., Которые могут быть дорогими и привести к неожиданному поведению. И это на самом деле ИМО очень просто реализовать.
pie6k
17

с самой последней версией 0.11 вы также можете просто вернуть null, чтобы контент не отображался.

Рендеринг в ноль

squiddle
источник
11

Я создал небольшой компонент, который обрабатывает это для вас: Reaction-toggle-display

Он устанавливает атрибут стиля на display: none !importantоснове hideили showреквизита.

Пример использования:

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
источник
10

Уже есть несколько хороших ответов, но я не думаю, что они были объяснены очень хорошо, и некоторые из приведенных методов содержат некоторые ошибки, которые могут сбить людей с толку. Итак, я собираюсь перейти к трем основным способам (плюс один не по теме), чтобы сделать это, и объяснить плюсы и минусы. Я в основном пишу это, потому что вариант 1 был рекомендован, и есть много потенциальных проблем с этим вариантом, если он не используется правильно.

Вариант 1: условный рендеринг в родительском.

Мне не нравится этот метод, если только вы не собираетесь визуализировать компонент один раз и оставить его там. Проблема заключается в том, что каждый раз при переключении видимости вы будете реагировать на создание компонента с нуля. Вот пример. LogoutButton или LoginButton условно отображаются в родительском LoginControl. Если вы запустите это, вы заметите, что конструктор вызывается при каждом нажатии кнопки. 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')
);

Теперь React довольно быстро создает компоненты с нуля. Тем не менее, он все равно должен вызывать ваш код при его создании. Так что если ваш конструктор, componentDidMount, рендер и т. Д. Код дорогой, то он будет значительно замедлять показ компонента. Это также означает, что вы не можете использовать это с компонентами с состоянием, где вы хотите, чтобы состояние сохранялось при скрытии (и восстанавливалось при отображении.) Одно преимущество заключается в том, что скрытый компонент вообще не создается до тех пор, пока он не выбран. Таким образом, скрытые компоненты не будут задерживать вашу начальную загрузку страницы. Также могут быть случаи, когда вы хотите, чтобы компонент с состоянием сбрасывался при переключении. В этом случае это ваш лучший вариант.

Вариант 2: условный рендеринг у ребенка

Это создает оба компонента один раз. Затем замыкает остальную часть кода рендеринга, если компонент скрыт. Вы также можете закоротить другую логику в других методах, используя видимую опору. Обратите внимание на файл console.log на странице кода. 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')
);

Теперь, если логика инициализации быстрая, а дочерние элементы не сохраняют состояния, вы не увидите разницы в производительности или функциональности. Однако зачем в любом случае заставлять React создавать новый компонент, каждый раз переключаясь? Однако если инициализация стоит дорого, вариант 1 будет запускать ее каждый раз, когда вы переключаете компонент, что замедляет страницу при переключении. Вариант 2 будет запускать все компоненты компонента при первой загрузке страницы. Замедление первой загрузки. Должен заметить еще раз. Если вы просто показываете компонент один раз на основе условия, а не переключаете его, или вы хотите, чтобы он сбрасывался при переключении toggledm, тогда вариант 1 подойдет и, вероятно, будет лучшим вариантом.

Однако, если медленная загрузка страницы является проблемой, это означает, что у вас есть дорогой код в методе жизненного цикла, и это, как правило, не очень хорошая идея. Вы можете и, вероятно, должны решить проблему медленной загрузки страницы, удалив дорогой код из методов жизненного цикла. Переместите его в асинхронную функцию, которая запускается ComponentDidMount, и пусть обратный вызов помещает ее в переменную состояния с помощью setState (). Если переменная состояния равна нулю, а компонент видим, тогда пусть функция рендеринга возвращает заполнитель. В противном случае визуализируйте данные. Таким образом, страница будет загружаться быстро и заполнять вкладки по мере их загрузки. Вы также можете переместить логику в родительский элемент и передать результаты дочерним элементам в качестве реквизита. Таким образом, вы можете определить приоритетность вкладок, которые будут загружены первыми. Или кэшируйте результаты и запускайте логику только при первом показе компонента.

Вариант 3: скрытие класса

Скрытие классов, вероятно, проще всего реализовать. Как уже упоминалось, вы просто создаете класс CSS с display: none и назначаете класс на основе prop. Недостатком является то, что весь код каждого скрытого компонента вызывается, и все скрытые компоненты присоединяются к DOM. (Вариант 1 вообще не создает скрытых компонентов. А Вариант 2 замыкает ненужный код, когда компонент скрыт, и полностью удаляет компонент из DOM.) Кажется, это быстрее при переключении видимости в соответствии с некоторыми тестами, выполненными комментаторами на другие ответы, но я не могу говорить с этим.

Вариант 4: один компонент, но изменить реквизит. Или, может быть, нет компонента вообще и кешировать HTML.

Это не будет работать для каждого приложения, и это не по теме, потому что речь не идет о скрытии компонентов, но может быть лучшим решением для некоторых случаев использования, чем скрытие. Допустим, у вас есть вкладки. Может быть возможно написать один React Component и просто использовать реквизит, чтобы изменить то, что отображается на вкладке. Вы также можете сохранить JSX для переменных состояния и использовать опору, чтобы решить, какой JSX вернуть в функции рендеринга. Если JSX должен быть сгенерирован, тогда сделайте это и кешируйте его в родительском и отправьте правильный как опору. Или сгенерируйте в дочернем элементе и кэшируйте его в дочернем состоянии и используйте реквизиты для выбора активного.

Kelnor
источник
9

Это хороший способ использовать виртуальный DOM :

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

Пример здесь

Использование 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>
  )
}

Пример здесь

daniloprates
источник
Мне нравится этот скудный ответ. Жаль, что скрипка не убежит.
Хуан Ланус
Как упоминалось в предыдущем ответе, вы неthis.setState() должны зависеть от состояния в .
Дэн Дакалеску
8

Вы устанавливаете логическое значение в состоянии (например, 'show)', а затем делаете:

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

return <div style={style}>...</div>
разбойник
источник
Я попробовал это, но событие click не переключило css для отображения блока. Я заблудился, как именно это сделать. Есть дополнительные советы?
user1725382
1
Это включает внесение активных изменений в таблицу правил стиля. Гораздо лучше иметь единственное существующее правило, которое вы можете включать и выключать, которое не является частью динамических свойств узла dom.
Джон Хаугеланд
1
Это действительно не имеет значения, если вы используете класс или стиль здесь ... вы, кажется, очень обеспокоены этим.
Разбойник
2
Использование класса быстрее на пару порядков. Это хорошо знать.
Джейсон Райс
1
Можно просто использовать условные имена классов с: github.com/JedWatson/classnames
backdesk
7

Лучшие практики приведены ниже в соответствии с документацией:

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

Рендеринг элемента только тогда, когда состояние является действительным.

динамический
источник
Этот ответ уже был дан годом ранее, поэтому сейчас можно удалить его.
Дан Дакалеску
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
источник
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
источник
4

Я начну с этого заявления от команды React:

В React вы можете создавать отдельные компоненты, которые инкапсулируют необходимое вам поведение. Затем вы можете отобразить только некоторые из них, в зависимости от состояния вашего приложения.

Условный рендеринг в React работает так же, как условия работают в JavaScript. Используйте JavaScript-операторы, такие как if или условный оператор, для создания элементов, представляющих текущее состояние, и дайте React обновить пользовательский интерфейс, чтобы соответствовать им.

По сути, вам нужно показать компонент при нажатии кнопки, вы можете сделать это двумя способами, используя чистый React или CSS, используя чистый React способ, вы можете сделать что-то вроде приведенного ниже кода в вашем случае, так что при первом запуске, результаты не отображаются как hideResultsесть true, но если нажать на кнопку, состояние изменится и hideResultsбудет, falseи компонент будет визуализирован снова с новыми условиями значения, это очень распространенное использование изменения представления компонента в 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);

Если вы хотите продолжить изучение условного рендеринга в React, посмотрите здесь .

Алиреза
источник
1
это должно быть самым элегантным способом!
пятого
4

Простой пример скрытия / показа с React Hooks: (извините за отсутствие скрипки)

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
источник
2
это может быть проще просто {показать? 1: 2}
Петр Чак
3

Если вы хотите увидеть, как переключить отображение компонента, проверьте эту скрипку.

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'));
Николас Портер
источник
3

Простой способ показать / скрыть элементы в React с использованием хуков

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

Теперь давайте добавим немного логики в наш метод рендеринга:

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

А также

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

Отличная работа.

superup
источник
2

В некоторых случаях может быть полезен компонент более высокого порядка:

Создайте компонент более высокого порядка:

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

Расширьте свой собственный компонент:

export const MyComp= HidableComponent(MyCompBasic);

Тогда вы можете использовать это так:

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

Это немного сокращает шаблон и обеспечивает соблюдение соглашений об именах, однако, пожалуйста, имейте в виду, что MyComp будет по-прежнему создаваться - способ опускания был упомянут ранее:

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

Vinga
источник
1

Используйте модуль 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
источник
1

Используйте ref и манипулируйте CSS

Одним из способов может быть использование React refи управление классом CSS с помощью API браузера. Его преимущество заключается в том, чтобы избежать повторного рендеринга в React, если единственная цель - скрыть / показать какой-либо элемент DOM одним нажатием кнопки.

// 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 Поправь меня, если я не прав. :)

UtkarshPramodGupta
источник
Например, созданный codeandbox.io, здесь: utgzx.csb.app , код находится по адресу codesandbox.io/embed/react-show-hide-with-css-utgzx
PatS
0

Если вы используете bootstrap 4, вы можете скрыть элемент таким образом

className={this.state.hideElement ? "invisible" : "visible"}
ThomasP1988
источник
0

Это также может быть достигнуто так (очень простой способ)

 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
источник
Пожалуйста, ознакомьтесь с настройкой «состояния на основе предыдущего состояния» на веб-сайте responsejs.org/docs/react-component.html#setstate . Также было бы неплохо исправить отступ в конце.
Дан Дакалеску
0

В этом примере показано, как можно переключаться между компонентами с помощью переключателя, который переключается через каждые 1 с.

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
источник
Что за странный URL-адрес изображения? Вы можете использовать стандартный сервис изображений-заполнителей, такой как placeimg.com
Дэн Даскалеску
0

Используйте этот простой и короткий синтаксис:

{ this.state.show && <MyCustomComponent /> }
Заин Уль Хасан
источник
Может быть, вы могли бы расширить свой синтаксис Lean & Short, чтобы объяснить, как он работает. Ой, подождите, это было сделано в ответе 3 года назад . Что ваш ответ снова приносит на стол?
Дэн Дакалеску
0

Вот простое, эффективное и лучшее решение с Classless React Component для показа / скрытия элементов. Использование React-Hooks, которое доступно в последнем проекте create -act-app , использующем 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;

Удачного кодирования :)

Реми Прасанна
источник
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;
}
Навед хан
источник
-1

Вы можете использовать файл CSS

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

и в файле CSS

    .search-results {
     ...
     display: none
     &.show {
      display: block
   }
}
армейский корпус
источник
-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);
Алан Пол Мэтью
источник
1
Можете ли вы объяснить, что вы сделали, и почему это лучше, чем принятый ответ?
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>
    );
  }
}
Мохаммад Голкар
источник
Можете ли вы добавить объяснение для лучшего понимания? Спасибо!
Шантешвар Инд
@ShanteshwarInde: это дублирует ту же идею из предыдущего ответа , включая неправильное использование setState в зависимости от текущего состояния. См. Responsejs.org/docs/react-component.html#setstate : «Если вам нужно установить состояние на основе предыдущего состояния, прочтите об аргументе средства обновления».
Дан Дакалеску
-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>

Венька
источник
4
Хотя этот код может ответить на вопрос, предоставление дополнительного контекста относительно того, почему и / или как этот код отвечает на вопрос, повышает его долгосрочную ценность.
xiawi
Что сказал @xiawi. Также, пожалуйста, используйте constвместо того, varкогда вы объявляете константы.
Дан Дакалеску