【问题标题】:REACT ES6 Update state from parents updated props来自父母更新道具的 REACT ES6 更新状态
【发布时间】:2017-12-28 23:17:10
【问题描述】:

我只是在遵循旧版本的 React 中的 Treehouse 教程,我试图在 ES6 中遵循它。

我有一个显示玩家数量和总分的统计组件。您可以添加玩家并更改分数,同时道具一直通过链条馈送。

您可以清楚地看到在“开发人员工具”中,在选择“添加新播放器时”更新道具的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 必须有办法。

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

【问题讨论】:

  • 当 props.players.length 改变它的值时,它不会反映在状态中,因为你已经在构造函数中定义了它,它只会在组件创建的第一次执行。
  • 你必须使用 setState() 来重新渲染组件,否则它永远不会改变它的值。尝试编写最少使用状态的代码以获得更好的性能。在你的情况下,道具就足够了。
  • 所以我假设Constructor运行了一次,但是我将setState()放在哪里,谢谢
  • 在您的情况下,您根本不应该使用状态。仅使用道具
  • 所以我知道我可以将两个道具直接放入模板中。但是在我正在观看的教程中,它被认为是干净的外面更好。我将更新我的问题以使其处于工作状态,但我的问题仍然存在,因为我不想有混乱的标记。

标签: reactjs ecmascript-6 state


【解决方案1】:

React“组件实例”在卸载之前不会被销毁。所以状态应该在组件的生命周期中改变。

另见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>
}

【讨论】:

  • 非常感谢你没有跳你直接给出解决方案的舞蹈:-)
猜你喜欢
  • 1970-01-01
  • 2020-06-19
  • 1970-01-01
  • 1970-01-01
  • 2019-04-17
  • 2020-03-07
  • 2020-11-10
  • 2017-11-23
  • 1970-01-01
相关资源
最近更新 更多