REACT ES6从父母更新道具更新状态

时间:2017-07-23 07:12:18

标签: reactjs ecmascript-6 state

我只是在一个较旧的React版本中关注树屋教程,我试图跟随ES6。

我有一个Stats组件,显示玩家数量和总分。你可以添加一个玩家并改变分数,同时道具通过链条一直进行。

您可以在选择Stats Dom元素时在开发者工具反应选项卡中清楚地看到,在添加新玩家时道具会更新。道具很好。

下面是代码:

import React, { Component } from 'react';
import PropTypes from 'prop-types';

class Stats extends Component {
  constructor(props) {
    super(props);

    this.state = {
      totalPlayers: props.players.length,
      totalPoints: props.players.reduce((total, player) => {
        return total + player.score;
      }, 0)
    };
  }

  render() {
    return (
      <table className="stats">
        <tbody>
          <tr>
            <td>Players:</td>
            <td>{this.state.totalPlayers}</td>
          </tr>
          <tr>
            <td>Total Points:</td>
            <td>{this.state.totalPoints}</td>
          </tr>
        </tbody>
      </table>
    );
  }
}

Stats.propTypes = {
  players: PropTypes.array.isRequired
};

export default Stats;

基本上,totalPlayers和totalPoints在加载时显示,但在进行任何进一步编辑时没有任何更新。我知道在渲染模板中我可以直接添加this.props.players.length以及props.players.reduce(...)并且它可以工作,但我认为这个从父问题状态更新的道具是一个阻止器我一直回答。

我知道它的工作原理如下

import React, { Component } from 'react';
import PropTypes from 'prop-types';

class Stats extends Component {  
  render() {
    return (
      <table className="stats">
        <tbody>
          <tr>
            <td>Players:</td>
            <td>{this.props.players.length}</td>
          </tr>
          <tr>
            <td>Total Points:</td>
            <td>{this.props.players.reduce((total, player) => {
                  return total + player.score;
                }, 0)}
            </td>
          </tr>
        </tbody>
      </table>
    );
  }
}

Stats.propTypes = {
  players: PropTypes.array.isRequired
};

export default Stats;

但我不想在标记中加入污物:-S必须有办法。

提前感谢您对此提出的任何建议。

1 个答案:

答案 0 :(得分:1)

React&#34;组件实例&#34;在卸下之前不会被销毁。所以应该在组件的生命周期中改变状态。

另见https://facebook.github.io/react/docs/react-component.html#componentwillreceiveprops

import React, { Component } from 'react';
import PropTypes from 'prop-types';

class Stats extends Component {
  constructor(props) {
    super(props);

    this.state = {
      totalPlayers: props.players.length,
      totalPoints: props.players.reduce((total, player) => {
        return total + player.score;
      }, 0)
    };
  }

  componentWillReceiveProps(nextProps) {
    const {players} = nextProps;

    this.setState({
      totalPlayers: players.length,
      totalPoints: players.reduce((total, player) => {
        return total + player.score;
      }, 0)
    });
  }

  render() {
    return (
      <table className="stats">
        <tbody>
          <tr>
            <td>Players:</td>
            <td>{this.state.totalPlayers}</td>
          </tr>
          <tr>
            <td>Total Points:</td>
            <td>{this.state.totalPoints}</td>
          </tr>
        </tbody>
      </table>
    );
  }
}

Stats.propTypes = {
  players: PropTypes.array.isRequired
};

export default Stats;

在这种情况下,我建议只使用道具。

getTotalCount() { return this.props.players.length; }

calcTotalPoints() {
    return this.props.players.reduce((total, player) => {
        return total + player.score;
    }, 0)
}

render() {
    <div>
        <div>{this.getTotalCount()}</div>
        <div>{this.calcTotalPoints()}</div>
    <div>
}