Показати або приховати елемент у React


532

Я вперше воюю з React.js і не можу знайти спосіб показати або приховати щось на сторінці за допомогою події клацання. Я не завантажую жодну іншу бібліотеку на сторінку, тому шукаю рідний спосіб за допомогою бібліотеки React. Це те, що я маю досі. Я хотів би показати поділ результатів, коли стартує подія натискання.

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

11
Прийнятий коментар використовує нову техніку, щоб зробити те, що існуючі технології на рідному рівні можуть робити як легше, швидше, так і зручніше з іншими мовами та бібліотеками. Поводження з цим за допомогою стандартного CSS - це майже напевно краща відповідь.
Джон Haugeland

13
@JohnHaugeland, найкраща відповідь при використанні рамки React - це прийнята відповідь, що відповідає стилю React, який має функції очищення, які в деяких випадках потрібно виконувати. Недобра практика, щоб компоненти просто ховалися в темряві. Якщо ви змішуєте речі, то краще перейдіть все рідне, що завжди швидше за все.
Клавдіу Хойда

4
Ні, це насправді не так. Використання реакції на винахід CSS - погана ідея.
Джон Хагеленд

8
Крім того, ви, здається, повністю пропустили суть того, що я сказала, а це - використовувати CSS, щоб приховати і показати елемент, а не використовувати React для фізичного його видалення. Ви можете використовувати React, щоб використовувати CSS, щоб приховати і показати елемент так само легко: <div style = {{display: this.props.example}} />.
Джон Хагеленд

5
@ClaudiuHojda, що компоненти ховаються в темряві, насправді дуже хороша практика в деяких випадках, я думаю про чуйну навігацію, де вам потрібні посилання, щоб вони залишалися в HTML, навіть якщо вони приховані css
Toni Leigh

Відповіді:


544

Реагуйте близько 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
Дуглас

53
Як зазначається в іншій відповіді, вставка / видалення набагато повільніше, ніж просте маскування класу.
Джон Haugeland

4
Я думаю, що коментарі Джонса потребують перегляду. Я пішов із задуманою відповіддю, і це було акуратно і 'відчував' більше, як реагують. Однак я не зміг встановити початкові стани і нічого корисного для відключеного компонента. Я переглядаю використання css, щоб приховати речі замість цього. Слухачі відмонтованих компонентів мовчки вийдуть з ладу, це завдало мені великої втрати часу сьогодні.
приземлився

Чи означає це, що react відобразить компонент, коли стиль зміниться (встановлено для показу / приховування) !?
алекс

@Douglas, якщо я цього не пропустив, цей спосіб не дозволяє повернутись до оригіналу. Я думаю, ОП може цього не хотіти, але як я можу це включити?
Черв’як

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 та просто не відображаються. Це може мати наслідки для продуктивності.
пмонт

125
Наслідки для продуктивності набагато гірші для додавання та вилучення елемента dom, ніж для його приховування та показу. Я усвідомлюю різницю між його підходом і моїм, і я вважаю, що у вас це зовсім неправильно. Будь ласка, знайдіть час, щоб визначити "наслідки для продуктивності", а потім виміряти його.
Джон Хагеленд

6
"Потоки гарантуються додаванням / видаленням" - не з абсолютно розташованими елементами, саме тому Famous отримує свої неймовірні показники. Але ви робите дійсну точку на показниках.
пмонт

9
про що це варто, це згадується в документах з реакцією тут: facebook.github.io/react/docs/…
Бред Паркс

85
Тому я просто перевірив повернення нуля і встановлення прихованого класу з 161 досить великими вузлами купола. Значно швидше використовувати клас, ніж видалити вузол.
Джонатан Роуні

120

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

{ 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, якщо запам'ятати цей стан по-іншому, було б складно)

2
Це чудовий приклад! Одна невелика річ, boxContent має бути className = "boxContent"
Bhetzie

5
Існує помилка тут: this.setState({isOpened: !isOpened});. Не змінюйте стан, коли ви модифікуєте стан. Ось хороший приклад: reactjs.org/docs / ... Так воно і повинно бути: this.setState( s => ({isOpened: !s.isOpened}) ). Зверніть увагу на функцію стрілки всередині setState.
аркол

Чи є у вас джерело / орієнтир / приклад, що підтверджує це "Якщо ви встановите дисплей: жоден - елемент все ще виводиться шляхом реакції та додається до DOM - це може погано вплинути на продуктивність." ?
neiya

@neiya Я не хочу. CSS може бути більш ефективною з малими елементами, але нерідко ви хочете вибирати великі частини вмісту, наприклад. вкладка. Крім того, хоча якийсь елемент прихований за допомогою CSS - він все ще живий у світі реагування. Це означає, що він може оновити стан, отримати деякі дані тощо, що може бути дорогим і призвести до несподіваної поведінки. І це IMO насправді дуже просто здійснити.
pie6k


11

Я створив невеликий компонент, який обробляє це для вас: 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 (
            <div>
                <input type="submit" value="Search" onClick={this.onClick} />
                <ToggleDisplay show={this.state.showResults}>
                    <Results />
                </ToggleDisplay>
            </div>
        );
    }
});

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

React.renderComponent(<Search />, document.body);

10

Вже є кілька чудових відповідей, але я не думаю, що їх пояснили не дуже добре, і кілька наведених методів містять деякі прийоми, які можуть відключити людей. Тому я перейду три основні способи (плюс один поза тематичний варіант), щоб зробити це і пояснити плюси і мінуси. Я в основному пишу це, тому що варіант 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 досить швидко створює компоненти з нуля. Однак він все одно повинен викликати ваш код під час його створення. Тож якщо ваш конструктор, компонентDidMount, візуалізація та ін кодується дорого, то він значно сповільнить показ компонента. Це також означає, що ви не можете використовувати це зі стаціонарними компонентами, де ви хочете, щоб стан зберігався, коли його заховано (і відновлено при відображенні). Так приховані компоненти не затримуватимуть початкове завантаження сторінки. Можуть також бути випадки, коли ви хочете, щоб стан компонента був скинутий під час переключення. У такому випадку це найкращий варіант.

Варіант 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 запустить усі вкладиші компонента при завантаженні першої сторінки. Уповільнення першого навантаження. Слід зазначити ще раз. Якщо ви просто показували компонент один раз на основі умови, а не перемикаєте його, або хочете його скинути під час toggglem, тоді варіант 1 - це добре і, мабуть, найкращий варіант.

Якщо повільне завантаження сторінки є проблемою, це означає, що у вас є дорогий код у способі життєвого циклу, і це, як правило, не гарна ідея. Ви можете, і, ймовірно, повинні вирішити повільне завантаження сторінки, перемістивши дорогий код із методів життєвого циклу. Перемістіть його до функції асинхронізації, яку розпочав ComponentDidMount, і зворотний виклик поставить її у змінну стану з setState (). Якщо змінна стану є нульовою, і компонент видно, тоді функція візуалізації повертає заповнювач. В іншому випадку надайте дані. Таким чином сторінка швидко завантажиться та заповнить вкладки під час завантаження. Ви також можете перенести логіку в батьківський і висувати результати дітям як реквізит. Таким чином ви можете визначити пріоритет, які вкладки завантажуються першими. Або кешуйте результати і виконайте лише логіку при першому появі компонента.

Варіант 3: Приховування класу

Заховання класів, мабуть, найлегше здійснити. Як згадувалося, ви просто створюєте клас CSS з дисплеєм: жоден та призначаєте клас на основі опори. Мінус - це весь код кожного прихованого компонента, який називається, і всі приховані компоненти прикріплені до DOM. (Варіант 1 взагалі не створює приховані компоненти. І варіант 2 короткого замикання непотрібний код, коли компонент прихований і повністю видаляє компонент з DOM.) Це здається, що це швидше при зміні видимості згідно з деякими тестами, зробленими коментаторами на інші відповіді, але я не можу з цим говорити.

Варіант 4: Один компонент, але змініть реквізити. А може взагалі немає компонента та кешувати HTML.

Цей не працюватиме для кожної програми, і це поза темою, оскільки мова не йде про приховування компонентів, але це може бути кращим рішенням для деяких випадків використання, ніж приховування. Скажімо, у вас є вкладки. Можливо, можливо, написати один Реактивний компонент і просто скористатися реквізитом, щоб змінити те, що відображається на вкладці. Ви також можете зберегти JSX у змінних стану та використовувати опору, щоб вирішити, який JSX повернути у функції візуалізації. Якщо JSX повинен бути згенерований, то зробіть це і кешуйте його в батьківському і надішліть правильний у якості опори. Або генеруйте в дитині та кешуйте її в стані дитини та використовуйте реквізит для вибору активного.


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

Приклад тут


Мені подобається ця худорлява відповідь. Шкода, що загадка не бігла.
Хуан Ланус

Як було сказано в попередній відповіді, ви неthis.setState() повинні залежати від стану в Росії .
Дан Даскалеску

8

Ви встановлюєте булеве значення в стані (наприклад, 'показ)', а потім виконайте:

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

return <div style={style}>...</div>

Я спробував це, але подія клацання не переключила css на блок відображення. Я втрачений, як саме це досягти. Будь-які додаткові поради?
користувач1725382

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

4
   class FormPage extends React.Component{
      constructor(props){
           super(props);
           this.state = {
             hidediv: false
           }
      }

     handleClick = (){
       this.setState({
          hidediv: true
        });
      }

      render(){
        return(
        <div>
          <div className="date-range" hidden = {this.state.hidediv}>
               <input type="submit" value="Search" onClick={this.handleClick} />
          </div>
          <div id="results" className="search-results" hidden = {!this.state.hidediv}>
                        Some Results
           </div>
        </div>
        );
      }
  }

4

Я починаю з цього твердження команди 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: (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;

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

Хороша робота.


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


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

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 Виправте мене, якщо я помиляюся. :)


Створено codeandbox.io, наприклад, тут: utgzx.csb.app , код знаходиться на codeandbox.io/embed/react-show-hide-with-css-utgzx
PatS

0

Якщо ви використовуєте bootstrap 4, ви можете приховати елемент таким чином

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

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

Прочитайте про налаштування "стану на основі попереднього стану" на reactjs.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);

Що з дивною URL-адресою зображення? Ви можете використовувати стандартну послугу заповнення зображень, наприклад placeimg.com
Дан Даскалеску,

0

Використовуйте цей худий і короткий синтаксис:

{ this.state.show && <MyCustomComponent /> }

Можливо, ви могли б розширити свій худий та короткий синтаксис, щоб пояснити, як це працює. О, зачекайте, це було зроблено у відповіді на 3 роки раніше . Що ваша відповідь знову приносить до столу?
Дан Даскалеску

0

Тут представлено просте, ефективне і найкраще рішення з компонентом безкласового реагування для показу / приховування елементів. Використання React-Hooks, який доступний в останньому проекті create-react-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>
    );
  }
}

Чи можете ви додати пояснення для кращого розуміння? Дякую!
Shanteshwar Inde

@ShanteshwarInde: це дублює ту саму ідею з попередньої відповіді , включаючи неправильне використання setState залежно від поточного стану. Див. Reakctjs.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коли оголошуєте константи.
Дан Даскалеску,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.