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

Я впервые общаюсь с React.js и не могу найти способ показать или скрыть что-то на странице с помощью события click. Я не загружаю какую-либо другую библиотеку на страницу, поэтому я ищу какой-то собственный способ, используя библиотеку React. Это то, что у меня есть до сих пор. Я хочу показать результаты div при срабатывании события click.

var Search= React.createClass({ handleClick: function (event) { console.log(this.prop); }, render: function () { return ( 
); } }); var Results = React.createClass({ render: function () { return (
Some Results
); } }); React.renderComponent( , document.body);

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

 var Search = React.createClass({ getInitialState: function() { return { showResults: false }; }, onClick: function() { this.setState({ showResults: true }); }, render: function() { return ( 
{ this.state.showResults ? : null }
); } }); var Results = React.createClass({ render: function() { return (
Some Results
); } }); ReactDOM.render(, document.getElementById('container'));

http://jsfiddle.net/kb3gN/15084/

  
 render: function() { return ( 
This will be hidden if you set props.shouldHide to something truthy.
); }

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

 { this.state.showMyComponent ?  : null } 

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

 { this.state.showMyComponent &&  } 

Бережливый


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

  

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

Вот мой подход с использованием ES6. Хотя принятый ответ верен, он довольно устарел.

 import React, { Component } from 'react'; // you should use ReactDOM.render instad of React.renderComponent import ReactDOM from 'react-dom'; class ToggleBox extends Component { constructor(props) { super(props); this.state = { // toggle box is closed initially isOpened: false, }; // http://egorsmirnov.me/2015/08/16/react-and-es6-part3.html this.toggleBox = this.toggleBox.bind(this); } toggleBox() { // check if box is currently opened const { isOpened } = this.state; this.setState({ // toggle value of `opened` isOpened: !opened, }); } render() { const { title, children } = this.props; const { isOpened } = this.state; return ( 
{title}
{isOpened && children && (
{children}
)}
); } } ReactDOM.render((
Some content
), document.getElementById('app'));

Демо: http://jsfiddle.net/kb3gN/16688/

Лучше сделать какой-то элемент только при необходимости, а не добавлять некоторые classы css с display: none . Если вы установили display: none – элемент все еще отображается, реагируя и добавляется в DOM что может плохо повлиять на производительность.

Представьте, что у вас есть страница с вкладками, каждая вкладка содержит много контента и сразу открывается только одна вкладка. Гораздо лучше держать в DOM только те элементы, которые должны отображаться.

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

 {opened && } 

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

 true && true && 2; // will output 2 true && false && 2; // will output false true && 'some string'; // will output 'some string' opened && ; // will output SomeElement if `opened` is true, will output false otherwise 

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

https://facebook.github.io/react/blog/2014/07/13/react-v0.11-rc1.html#rendering-to-null

Я создал небольшой компонент, который обрабатывает это для вас: https://www.npmjs.com/package/react-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 ( 
); } }); var Results = React.createClass({ render: function() { return (
Some Results
); } }); React.renderComponent(, document.body);

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

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

Уже есть несколько отличных ответов, но я не думаю, что они были объяснены очень хорошо, и некоторые из приведенных методов содержат некоторые ошибки, которые могут вызвать людей. Поэтому я собираюсь пересмотреть три основных способа (плюс один вариант вне темы), чтобы сделать это и объяснить плюсы и минусы. Я в основном пишу это, потому что Вариант 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 = ; } else { button = ; } return ( 
{button}
); } } class LogoutButton extends React.Component{ constructor(props, context){ super(props, context) console.log('created logout button'); } render(){ return ( ); } } class LoginButton extends React.Component{ constructor(props, context){ super(props, context) console.log('created login button'); } render(){ return ( ); } } function UserGreeting(props) { return

Welcome back!

; } function GuestGreeting(props) { return

Please sign up.

; } function Greeting(props) { const isLoggedIn = props.isLoggedIn; if (isLoggedIn) { return ; } return ; } ReactDOM.render( , document.getElementById('root') );

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

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

Это создает оба компонента один раз. Затем замыкает остальную часть кода визуализации, если компонент скрыт. Вы также можете закорачивать другую логику другими способами, используя видимую опору. Обратите внимание на console.log на странице 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 ( 
); } } class LogoutButton extends React.Component{ constructor(props, context){ super(props, context) console.log('created logout button'); } render(){ if(!this.props.isLoggedIn){ return null; } return ( ); } } class LoginButton extends React.Component{ constructor(props, context){ super(props, context) console.log('created login button'); } render(){ if(this.props.isLoggedIn){ return null; } return ( ); } } function UserGreeting(props) { return

Welcome back!

; } function GuestGreeting(props) { return

Please sign up.

; } function Greeting(props) { const isLoggedIn = props.isLoggedIn; if (isLoggedIn) { return ; } return ; } ReactDOM.render( , document.getElementById('root') );

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

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

Вариант 3: Скрытие classа

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

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

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

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

React:

  var Comp = React.createClass({ getInitialState: function(){ return {hide: false}; }, toggle: function(){ this.setState({hide: !this.state.hide}); }, render: function() { return 
Hi there
; } }); ReactDOM.render( , document.getElementById('container') );

CSS

  .hide-true { display: none; } 

Скриншот здесь

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

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 ( 

yoyoyoyoyo

); } }); ReactDOM.render( , document.getElementById('container'));

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

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

 export var HidableComponent = (ComposedComponent) => class extends React.Component { render() { if ((this.props.shouldHide!=null && this.props.shouldHide()) || this.props.hidden) return null; return ; } }; 

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

 export const MyComp= HidableComponent(MyCompBasic); 

Затем вы можете использовать его следующим образом:

   

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

{ !hidden && }

Я начинаю с этого заявления из команды 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 ( 
{ !this.state.hideResults && }
); } }); var Results = React.createClass({ render: function() { return (
Some Results
); } }); ReactDOM.render(, document.body);

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

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

  {this.state.showFooter && 
}

Отображать элемент только в том случае, если состояние действительно.

  class FormPage extends React.Component{ constructor(props){ super(props); this.state = { hidediv: false } } handleClick = (){ this.setState({ hidediv: true }); } render(){ return( 
); } }
  • Что такое mapDispatchToProps?
  • ReactJS: Почему передается исходное состояние компонента prop-анти-шаблон?
  • React: обработчик onClick получает вызов для каждого рендеринга?
  • Передайте несколько параметров обработчикам событий в React
  • Ограничение импорта приложений create-react-app вне каталога src
  • Что такое использование Curly Braces в заявлении импорта ES6
  • Как сообщить серверу webpack dev для обслуживания index.html для любого маршрута
  • Есть ли способ проверить, отключен ли компонент реакции?
  • Реагировать на фокус на ввод после рендера
  • Используйте функции жизненного цикла componentWillMount или componentDidMount для запроса async в React
  • Невозможно прочитать свойство 'map' неопределенного в React
  • Interesting Posts

    java.lang.RuntimeException: сбой takePicture

    Может ли лицензия, купленная в одной стране, использоваться в другой стране?

    iPhone – UIImagePickerControllerDelegate наследование

    Как вы создаете массив структур в C?

    Инструмент для аннотирования изображений (скриншоты) для целей документации?

    Бесплатная утилита для преобразования DTD в XSD?

    Должен ли ServiceStack быть служебным слоем в приложении MVC или должен ли он вызвать сервисный уровень?

    Преобразование строки в шестнадцатеричный в Java

    Создавать HTTP-запрос и получать ответ с помощью приложения консоли C #

    Бесплатное программное обеспечение для преобразования видео, которое поддерживает широкоэкранный формат

    MVC Vs n-level архитектура

    Доводы за и против доступа к данным (MS Access front end с SQL Server Backend)

    CRTP, чтобы избежать динамического polymorphismа

    Могу ли я искать и заменять макрос Notepad ++?

    Как получить ключи F1-F12 для переключения экранов на экране gnu в cygwin при подключении через SSH?

    Давайте будем гением компьютера.