Можно ли изменить значение в элементе без изменения состояния? - PullRequest
0 голосов
/ 21 мая 2018

У меня есть код, подобный приведенному ниже;

class Comment extends Component {
  constructor(props) {
    super(props);
    const color = "red";
  }
  changeColor() {
    this.color = "blue";
    console.log(this.color);
  }
  render() {
    return(
      <div className="CommentPlaceHolder" style={{backgroundColor: this.color}}>
        <form id="form1">
          <textarea onFocus={this.changeColor} className="comment" id="feed" name="subject" placeholder="Write something.."></textarea>
          <button type="submit" form="form1">Paskelbti</button>
        </form>        
      </div>
    );
  }
}

export default Comment;

У меня есть textarea внутри div контейнера, и я хочу, чтобы при щелчке мышью по textarea изменился цвет div контейнера,Я перепробовал много вещей и все провалилось.Можно ли сделать это без состояний?

Ответы [ 4 ]

0 голосов
/ 21 мая 2018

Я бы не рекомендовал обновлять DOM вручную и не рекомендовал бы вызывать this.forceUpdate () - это не очень хорошая практика для React.

Использование setState () - это правильный способ получитьправильный результат вы собираетесь.Для небольшого, простого приложения, я думаю, вы могли бы сделать что-то вроде этого:

import React, { Component } from 'react'
import styled from 'styled-components'

export default class ChangingDiv extends Component {

  state = {
    bgColor: 'red'
  }

  handleColorChange = () => {
    const { bgColor } = this.state

    bgColor === 'red'
    ?
    this.setState({ bgColor: 'blue' })
    :
    this.setState({ bgColor: 'red' })
  }

  render() {
    const { bgColor } = this.state
    return (
      <ColorDiv color={bgColor}>
        <TextBox
          onFocus={this.handleColorChange}
          onBlur={this.handleColorChange}
        />
      </ColorDiv>
    )
  }
}

const ColorDiv = styled.div`
  width: 100%;
  height: 300px;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: ${props => props.color};
`
const TextBox = styled.textarea`
  width: 300px;
  padding: 20px;
  font-size: 16pt;
`

Используя стилизованные компоненты, вы можете установить цвет на основе состояния.Здесь я устанавливаю цвет фона ColorDiv, чтобы он соответствовал состоянию bgColor.Когда он меняется, меняется и цвет фона.Вы могли бы даже добавить длительность перехода в ColorDiv для более плавного перехода.

Если вы не используете стилизованные компоненты, вы могли бы по сути сделать то же самое, за исключением того, что вместо пропеллера состояния bgColor вы сделали бы егоимя класса.Имя класса изменится, когда вы сфокусируете и запачкаете поле ввода:

import React, { Component } from 'react'

export default class ChangingDiv extends Component {

  state = {
    className: 'red'
  }

  handleColorChange = () => {
    const { className } = this.state

    className === 'red'
    ?
    this.setState({ className: 'blue' })
    :
    this.setState({ className: 'red' })
  }

  render() {
    const { className } = this.state
    return (
      <div className={className}>
        <textarea
          onFocus={this.handleColorChange}
          onBlur={this.handleColorChange}
        />
      </div>
    )
  }
}

Если вы все еще не хотите устанавливать величественный цвет, тогда вы всегда можете сделать традиционный document.getElementById ('# colorDiv')и изменить цвет таким образом.Но это нарушит правила React, потому что вы будете манипулировать DOM напрямую.

0 голосов
/ 21 мая 2018

Вы можете позвонить this.forceUpdate(), чтобы вызвать повторную визуализацию, но это не рекомендуется.Почти всегда лучше просто обновить состояние.

См. Документы

0 голосов
/ 21 мая 2018

Чтобы внести изменения в ваш пользовательский интерфейс, необходимо выполнить повторную визуализацию компонента.Для повторного рендеринга компонента необходимо изменить либо ваше состояние, либо реквизиты, либо вам нужно позвонить forceUpdate (что не рекомендуется)

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

constructor(props) {
   super(props);
   this.state = { color: 'red' };
}
changeColor = () => {
  this.setState({color: "blue"});
}
render() {
  return(
    <div className="CommentPlaceHolder" style={{backgroundColor: this.state.color}}>
       {/* some other code */}
    </div>
  );
}
0 голосов
/ 21 мая 2018

Пара вещей:

Во-первых, способ объявления цвета в constructor.Вы только что объявили локальный const, который не будет доступен из компонентов других функций.Правильный способ объявить это будет использовать this:

super(props);
   this.color = "red";
}

Далее, в событии onFocus в текстовой области вы не запускаете функцию соответствующим образом.Для этого используйте жирную стрелку, например:

<textarea onFocus={() => this.changeColor()} className="comment" id="feed" name="subject" placeholder="Write something.."></textarea>

Сейчас ... Проблема с тем фактом, что вы не используете состояние, заключается в том, что при изменении атрибутов компонента он неавтоматически перерисовать, как это происходит при использовании this.setState.Таким образом, вам придется заставить его перерисовать.К счастью, есть функция this.forceUpdate().Поэтому в функции changeColor просто вызовите ее.

changeColor() {
  this.color = "blue";
  console.log(this.color);
  this.forceUpdate()

}

. Вот рабочая версия этих изменений:

class App extends React.Component {
  constructor(props) {
    super(props);
        this.color = "red";
    }
        changeColor() {
            this.color = "blue";
            console.log(this.color);
          this.forceUpdate()
        }
        render() {
            return(
                <div className="CommentPlaceHolder" style={{backgroundColor: this.color}}>
                    <form id="form1">
                        <textarea onFocus={() => this.changeColor()} className="comment" id="feed" name="subject" placeholder="Write something.."></textarea>
                        <button type="submit" form="form1">Paskelbti</button>
                    </form>

                </div>
        );
    }
}

ReactDOM.render(
    <App />,
    document.getElementById('app')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
...