使用map时,React'无法读取undefined的属性'

VWa*_*ang 7 javascript frontend reactjs

我正在从teamtreehouse.com制作一个非常基本的React应用程序,而且我经常遇到

"TypeError:无法读取未定义的属性'onPlayerScoreChange'"

即使我正确绑定我的功能(我认为)

'onPlayerScoreChange'Grandparent组件中的一种方法,当用户点击"+"或" - "按钮更改玩家的分数时执行该方法.

如果有人可以解释错误,那将是非常有帮助的,因为我认为我正在设置this.onPlayerScoreChange = this.onPlayerScoreChange.bind(this)伟大的祖父母的构造函数.

父组件:

class App extends React.Component {
constructor(props) {
    super(props);
    this.onPlayerScoreChange = this.onPlayerScoreChange.bind(this)
    this.state = {
        initialPlayers: props.initialPlayers,
    };
}

onPlayerScoreChange(delta, index) {
    this.setState((prevState, props) => {
        return {initialPlayers: this.prevState.initialPlayers[index].score += delta}
    })
}

render() {
    return(
        <div className = "scoreboard">
            <Header title = {this.props.title}/>
            <div className = "players">
                {this.state.initialPlayers.map(function(player, index) {
                    return(
                        <Player 
                        name = {player.name} 
                        score = {player.score} 
                        key = {player.id} 
                        index = {index}
                        onScoreChange = {this.onPlayerScoreChange}
                        />
                    )
                })}
            </div>
        </div>
    )
}}
Run Code Online (Sandbox Code Playgroud)

(组件具有标题的默认道具)

子组件:

class Player extends React.Component {
render() {
    return(
        <div className = "player">
            <div className = "player-name">
                {this.props.name}
            </div>
            <div className = "player-score">
                <Counter score = {this.props.score} onChange = {this.props.onScoreChange} index = {this.props.index}/>
            </div>
        </div>
)
}}
Run Code Online (Sandbox Code Playgroud)

孙子组件:

class Counter extends React.Component {
constructor(props) {
    super(props)
    this.handleDecrement = this.handleDecrement.bind(this)
    this.handleIncrement = this.handleIncrement.bind(this)
}

handleDecrement() {
    this.props.onChange(-1, this.props.index)
}

handleIncrement() {
    this.props.onChange(1, this.props.index)
}

render() {
    return(
        <div className = "counter">
            <button className = "counter-action decrement" onClick = {this.handleDecrement}> - </button>
            <div className = "counter-score"> {this.props.score} </div>
            <button className = "counter-action increment" onClick = {this.handleIncrement}> + </button>
        </div>
)}}
Run Code Online (Sandbox Code Playgroud)

谢谢!

Shu*_*tri 10

您尚未对使用的地图功能进行绑定onScoreChange = {this.onPlayerScoreChange},

您可以使用绑定或箭头功能进行绑定

PS绑定是必需的,因为map函数的上下文与React Component上下文不同,因此this在此函数内部将不会引用React组件this,因此您无法访问React Component类的属性.

使用箭头功能:

 {this.state.initialPlayers.map((player, index)=> {
                return(
                    <Player 
                    name = {player.name} 
                    score = {player.score} 
                    key = {player.id} 
                    index = {index}
                    onScoreChange = {this.onPlayerScoreChange}
                    />
                )
            })}
Run Code Online (Sandbox Code Playgroud)

有了绑定

   {this.state.initialPlayers.map(function(player, index) {
                return(
                    <Player 
                    name = {player.name} 
                    score = {player.score} 
                    key = {player.id} 
                    index = {index}
                    onScoreChange = {this.onPlayerScoreChange}
                    />
                )
            }.bind(this))}
Run Code Online (Sandbox Code Playgroud)