Компонент React не обновляется из реквизита

Я упростил код, чтобы изолировать и воспроизвести проблему, поэтому в реальных реализациях это может не иметь смысла:

import React, { Component } from 'react'

const obj = {
    objProp: true
};

export default class MyButtonContainer extends Component {
    render() {
        return (
            <MyButton
                onClick = {() => {obj.objProp = !obj.objProp;}}
                text = {obj.objProp.toString()}
            />
        );
    }
}

class MyButton extends Component {
    render() {
        return (
            <button
                onClick = {this.props.onClick}
            >
                {this.props.text}
            </button>
        )
    }
}

Вы можете видеть, что obj.objProp назначается в MyButton.props.text, и его значение переключается, когда вы щелкаете по экземпляру MyButton. Значение obj.objProp действительно изменяется, как ожидалось, но MyButton не обновляется и не обновляется.

У меня вопрос: почему MyButton не обновляется и как правильно реализовать такую ​​логику?

Вдобавок, если решение состоит в том, чтобы вставить obj в MyButtonContainer.state, почему MyButton будет обновляться, если я использовал Redux, который вводит данные только в реквизиты без изменения состояния?

Спасибо :)

автоматически он не будет повторно отображен, вам нужно сообщить, чтобы отреагировать на его обновление, либо используйте forceUpdate (this.forceUpdate(); внутри обработчика кликов), либо используйте переменную состояния.

Mayank Shukla 11.12.2018 07:44
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
2
1
5 818
3

Ответы 3

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

Измените контейнер для кнопок на это.

export default class MyButtonContainer extends Component {

  constructor() {
    this.state = {
      objProp: true
    }
    this.onclick = this.onclick.bind(this);
  }

  onclick() {
    this.setState({ objProp: !this.state.objProp })
  }

  render() {
    return (
      <MyButton
        onClick = {() => { this.onclick() }}
        text = {this.state.objProp.toString()}
      />
    );
  }
}

Демо

Спасибо за ваш ответ. Так почему же при использовании Redux компонент обновляется, хотя Redux управляет только this.props без доступа к состоянию?

Binoman 12.12.2018 06:46

Redux обновляет компонент, и вы, должно быть, делаете что-то не так.

Just code 12.12.2018 06:48

Используйте государство, чтобы держать свой objProp

React выполнит повторную визуализацию, когда будет вызван setstate, он не будет повторно отображен автоматически.

export default class MyButtonContainer extends Component {

      state = {
          objProp: true
      }

      onclick = () => {
        this.setState({ objProp: !this.state.objProp })
      }

      render() {
        return (
          <MyButton
            onClick = {() => { this.onclick() }}
            text = {this.state.objProp.toString()}
          />
        );
      }
    }
}

Всякий раз, когда есть что-то, в чем вы хотите, чтобы пользовательский интерфейс изменился, это должно быть либо через Состояние, либо через реквизит, переданное ему.

Оба приведенных ответа верны, если вы хотите повторно отрисовать свой компонент, вы должны использовать this.setState. поэтому есть два способа получить обновленные данные в React Component.

1) поместите ваш объект в состояние и установитеState. 2) если вы действительно не хотите использовать свой объект в состоянии, вы можете сделать обходной путь, например, взять переменную i в своем состоянии, и при назначении данных в вашем объекте просто выполните this.setState ({i + 1}), поэтому из-за изменение состояния приведет к повторной визуализации вашего компонента, хотя это не лучший способ решить эту проблему, потому что для повторной визуализации вы должны установить состояние.

import React, { Component } from 'react'
constructor(props){
 super(props);
 this.state = {i:0}
}
const obj = {
   objProp: true
};

export default class MyButtonContainer extends Component {
   render() {
      return (
          <MyButton
              onClick = {() => {
                      obj.objProp = !obj.objProp ;
                      let {i} = this.state ; 
                      i = i + 1; 
                      this.setState(i)}}
                      text = {obj.objProp.toString()}
          />
      );
   } 
}

class MyButton extends Component {
  render() {
      return (
          <button
              onClick = {this.props.onClick}
          >
             {this.props.text}
          </button>
      )
   } 
}

Спасибо за ваш ответ. Так почему, когда я использую Redux, компонент обновляется, даже если Redux управляет только this.props?

Binoman 11.12.2018 14:11

Да, потому что проверьте свою конфигурацию redux, вы обновляете состояние и передаете его всем компонентам через реквизиты. Redux создает состояние для хранения данных, которые вы можете передавать через реквизиты во все компоненты. для получения дополнительной информации redux.js.org/basics/data-flow

Amit Chauhan 13.12.2018 13:18

Но по моему мнению, состояние магазина не связано с состоянием компонентов. Состояние хранилища - это просто текущее состояние объекта хранилища, содержащего данные, в отличие от состояния и свойств компонента, которые, помимо прочего, отвечают за представление компонентов в DOM, и они не могли ' t / не следует манипулировать напрямую (скорее, через setState и т. д.). Я правильно понял? мои предположения верны?

Binoman 21.12.2018 13:24

Другие вопросы по теме