Я пытаюсь использовать компонент React с отслеживанием состояния с ES6, но когда я определяю конструктор, конструктор будет вызываться только один раз, а компонент визуализируется несколько раз (из его родителя). Пример показан ниже.

class SubComponent extends React.Component {
  constructor(props) {
    super(props);
    console.log("Creating sub component");
    this.state = { count: props.count };
  }

  render() {
    console.log("Rendering sub component", this.state.count);
    return (<div>count: {this.state.count}</div>);
  }
}

class App extends React.Component {
  constructor(props) {
    super(props);
    console.log("Creating app");
    this.state = { count: 0 };
    this.tick = this.tick.bind(this);
    setInterval(this.tick, 1000);
  }

  tick() {
    this.setState({ count: this.state.count + 1 });
  }

  render() {
    console.log("Rendering app", this.state.count);
    return (<SubComponent count={this.state.count} />);
  }
}

Это не будет обновлять визуализированный вывод (это всегда будет count: 0), но журналы будут выводить:

Creating app
Rendering app 0
Creating sub component
Rendering sub component 0
Rendering app 1
Rendering sub component 0
Rendering app 2
Rendering sub component 0
Rendering app 3
Rendering sub component 0
...

Вот JSFiddle: http://jsfiddle.net/jor0xu1a/1/

Я знаю, что в примере SubComponent состояние не требуется, но я постарался сделать его как можно проще, чтобы показать мою проблему.

Что мне не хватает?

0
Karl Thunberg 4 Янв 2016 в 23:02

4 ответа

Лучший ответ

Я рекомендую прочитать Свойства в getInitialState - это анти- Выкройка.

По сути, как можно меньше компонентов должны иметь состояние. Как уже говорилось в других ответах, в вашем случае вы можете просто использовать this.props.count для ссылки на текущее значение. Кажется, нет причин, по которым SubComponent должен иметь собственное состояние.

Однако, если вы действительно хотите вычислить состояние компонента из свойств, которые он получает, вы несете ответственность за их синхронизацию с помощью метода жизненного цикла componentWillReceiveProps:

componentWillReceiveProps(nextProps) {
    this.setState({count: nextProps.count});
}
2
Felix Kling 4 Янв 2016 в 22:14

Плохо, я думал, что конструктор (или getInitialState для ES5) вызывается всякий раз, когда компонент повторно отрисовывается родителем (я думал, что родитель «воссоздает» своих потомков при рендеринге), но это не всегда так. Я должен был прочитать об этом (url ) и попробовал это с ES5 ( jsFiddle), прежде чем подумать, что я чего-то не понял с ES6 и вопрос здесь.

И да, в примере SubComponent должен использоваться this.props, но мой вариант использования имел фактическую функциональность с отслеживанием состояния в моем реальном компоненте. Я создал пример, так как почему-то думал, что результат не был ожидаемым результатом при использовании ES6 (но это было).

Спасибо за ваш отзыв!

0
Karl Thunberg 4 Янв 2016 в 22:17

Ваш подкомпонент должен быть:

 class SubComponent extends React.Component {
      constructor(props) {
        super(props);
        console.log("Creating sub component");
      }

      render() {
        return (<div>count: {this.props.count}</div>);
      }
    }
0
Florim Maxhuni 4 Янв 2016 в 20:11

В субкомпоненте это props, а не состояние - измените его на this.props.count, и это будет работать

3
Kania 4 Янв 2016 в 20:08