2017-07-23 62 views
0

我只是在一个旧的verison React中跟随一个Treehouse教程,我正在尝试使用ES6。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

当props.players.length改变其价值并不在状态反映,因为你已经在构造函数中定义它和组件已被创建时,将只执行上是第一次。 –

+0

您必须使用setState()重新渲染组件,否则它将永远不会更改其值。尝试编写最低限度的状态以获得更好的性能。就你而言,道具就足够了。 –

+0

所以我假设构造函数运行了一次,但是我会在哪里放置setState(),谢谢 – Pocketninja

回答

1

反应“组件实例”直到卸载才会被销毁。所以应该改变组件的生命周期。

参见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> 
} 
+0

非常感谢你,你没有跳舞,你直接给了解决方案的舞蹈:-) – Pocketninja