5 Вопрос: Как изменить свойство стиля на кнопке onClick в React?

вопрос создан в Thu, May 2, 2019 12:00 AM

У меня есть элемент реагирования, который я хочу скрыть при нажатии кнопки.

Стили элементов загружаются в конструктор следующим образом:

 constructor(props) {
super(props);
this.state = {
  display: 'block'
};
this.ElementStyle= {
  width: '100%',
  backgroundColor: '#F6F6F6',
  color: '#404040',
  padding: '8px 15px',
  boxSizing: 'content-box',
  position: 'fixed',
  bottom: '0',
  display: this.state.display
    }
  }

И у элемента есть кнопка внутри его render (), вызывающая функцию, которая изменяет состояние следующим образом:

render()  {
  <button onClick={this.Method.bind(this)}>Click me </button>
}

И метод ():

  Method() {
    this.setState({
      display: 'none'
    });
  }

И тогда у меня есть это:

  shouldComponentUpdate() {
    this.ElementStyle.display = this.state.display;
  }

Это, однако, говорит: "TypeError: "display" is read-only"

    
2
  1. В моем текущем проекте я использовал jquery в методе componentDidMount () для достижения этой цели. Однако я видел рекомендации против этого, поэтому я тоже хотел бы увидеть мысли по этому поводу.
    2019-05-02 15: 20: 56Z
  2. Если вы используете jquery в реагировать (если вы не переносите не реагирующую библиотеку), возможно, вы используете ее неправильно. Есть несколько подходов к этой задаче, и самый простой - определить два класса в вашем CSS и переключить className (не полагаясь на jQuery)
    2019-05-02 15: 24: 47Z
  3. @ MosèRaguzzini Ну, я не импортировал jquery просто для метода переключения, это точно. Но я понимаю, что вы говорите, я также использовал vanilla js и css для этой задачи. Моя точка зрения заключается в том, что включение всех этих разных вещей в состояние компонента становится утомительным. Мое восприятие состояния состояло в том, что оно предназначено для отслеживания вводимых пользователем данных. Когда вы начинаете хранить основные функциональные возможности пользовательского интерфейса в состоянии, я думаю, это кажется излишним. Мне придется привыкнуть к этому понятию, поскольку это, по-видимому, «правильный» способ.
    2019-05-02 15: 46: 14Z
  4. Зависит от того, что я обычно сохраняю состояние пользовательского интерфейса в Redux вместе с данными, так как при обнаружении ошибки BugSnag отправляет полную историю состояний моему отладчику, и я могу воспроизвести оба данные и состояние пользовательского интерфейса при возникновении ошибки. Несомненно, что лучше управлять одним CSS в CSS /Styled-components /SASS /LESS или аналогичном и принимать во внимание простую работу с классами
    2019-05-02 16: 01: 50Z
5 ответов                              5                         

Просто поместите ваши стили в состояние:

State

this.state = {
  ElementStyle: {
  width: '100%',
  backgroundColor: '#F6F6F6',
  color: '#404040',
  padding: '8px 15px',
  boxSizing: 'content-box',
  position: 'fixed',
  bottom: '0',
  display: 'block
};

Метод

 Method() {
    this.setState({
      ElementStyle: {
      ...this.state.ElementStyle,
      display: 'none'
      }
    });
  }

Рендер

render()  {
  <button style={this.state.ElementStyle} onClick={this.Method.bind(this)}>Click me </button>
}
    
3
2019-05-02 15: 21: 22Z
  1. Этот вопрос я часто задавал. Что должно быть включено в состояние? Я начал это делать, и мой объект состояния стал ОЧЕНЬ захламленным в одном из моих компонентов. Это считается хорошей практикой?
    2019-05-02 15: 22: 34Z
  2. Управление CSS из состояния - плохая идея. Свойство display всегда отображает элемент независимо от его состояния. Таким образом, хорошая практика - не отображать элемент вообще, если состояние ложно.
    2019-05-02 15: 24: 21Z
  3. @ silencedogood может быть, вам нужно реорганизовать этот один компонент. Пример: < my-button />
    2019-05-02 15: 27: 10Z
  4. @ AnandGhaywankar вы правы, но не по правильной причине. Манипулировать стилями в состоянии плохо для разделения задач, представьте себе, что нужно добавить полное управление css в каждый компонент для каждого элемента. Вот почему я использую styled-components /css modules /plain css. Другим дополнительным способом является возврат css методом, который проверяет состояние. Но на самом деле старомодный «подход с двумя классами CSS» для этой задачи лучше всего подходит.
    2019-05-02 15: 27: 34Z
  5. @ wakajawaka да, возможно. У меня там было состояние ленивого загрузчика, css, всякого рода вещи. Наконец я пошел с jquery, чтобы свести на нет вещи. Рефакторинг, безусловно, будет лучшим ответом, я полагаю. Однако в некоторых случаях такая большая модульность может раздражать.
    2019-05-02 15: 36: 08Z

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

// css
.yoourclass {
 width: '100%',
  backgroundColor: '#F6F6F6',
  color: '#404040',
  padding: '8px 15px',
  boxSizing: 'content-box',
  position: 'fixed',
  bottom: '0',
  display: none
    }

}

//have a class that show display to block
.show {
  display: block;
}

Тогда в вашем JavaScript

// set your state to some display property 
this.state = {
   showHiddenElement: false
}

//then you can set state to display css like
const {showHiddenElement} = this.state;
this.setState({
  showHiddenElement: !showHiddenElement
})
// and in your component 
// apply the class bases on the state like
const toggle = this.state.showHiddenElement;
<yourelement className={`yoourclass ${toggle? 'show' : ''}`}

Что-то в этом роде, надеюсь, это имеет смысл, дайте мне знать. Это другой подход.

    
0
2019-05-02 15: 37: 55Z

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

constructor(props) {
    super(props);
    this.state = {
       display: 'block'
    };
}


Method() {
   this.setState({
       display: 'none'
   });
}


render()  {
  <div>
     <div style={{display: this.state.display}} ></div>
     <button onClick={this.Method.bind(this)}>Click me </button>
  </div>
}

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

    
0
2019-05-02 17: 19: 47Z

Я не уверен, почему вы пытаетесь установить стиль с помощью свойства style, но обычно мы делаем это с помощью классов CSS и таблиц стилей CSS. И во время выполнения мы модифицируем классы вместо стилей элементов.

Итак, для вашего случая у нас будет такой стиль, как у некоторого класса, например, в App.scss

.class-to-be-applied {
    width: 100%;
    background-color: #F6F6F6;
    color: #404040;
    padding: 8px 15px;
    box-sizing: content-box;
    position: fixed;
    bottom: 0;

    .no-display {
        display: none;
    }
}

и в App.js,

import React, { Component }  from 'react';
import classnames from 'classnames';
import './App.scss';

class MyComponent extends Component {
    constructor(props) {
        super(props);
        this.state = {
            display: true
        };
    }
    handleButtonClick = () => {
        this.setState(({ display }) => ({display: !display}));
    }
    render()  {
        return (
            <div>
                <button onClick={this.handleButtonClick}>Click me </button>
                <SomeComponent className={classnames('class-to-be-applied', {'no-display': !this.state.display})} />
            </div>
        );
    }
}

Другой способ сделать то же самое и более предпочтительный способ - просто не отображать его вообще, чтобы избежать вставки в само дерево, как показано ниже для App.js,

import React, { Component }  from 'react';
import classnames from 'classnames';
import './App.scss';

class MyComponent extends Component {
    constructor(props) {
        super(props);
        this.state = {
            display: true
        };
    }
    handleButtonClick = () => {
        this.setState(({ display }) => ({display: !display}));
    }

    render()  {
        return (
            <div>
                <button onClick={this.handleButtonClick}>Click me </button>
                { this.state.display && <SomeComponent className=class-to-be-applied' /> }
            </div>
        );
    }
}
    
0
2019-05-05 19: 22: 33Z

1) Поместите ваш объект во встроенный CSS: -

render() {
    return (
        <div>
            <button onClick={ this.Method.bind(this) }>Click me </button>
            <h1 style={{
                 width: '100%',
                 backgroundColor: '#F6F6F6',
                 color: '#404040',
                 padding: '8px 15px',
                 boxSizing: 'content-box',
                 position: 'fixed',
                 bottom: '0',
                 display:this.state.display
            }}>About</h1>
        </div>
    )
}

2) И удалите эту shouldComponentUpdate () функцию

 shouldComponentUpdate() {
this.ElementStyle.display = this.state.display;
}
    
0
2019-05-05 19: 52: 38Z
источник размещен Вот