使用地图时反应'无法读取未定义的属性'

2022-01-19 00:00:00 reactjs frontend javascript

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

I'm making a very basic React app from teamtreehouse.com, and I'm constantly encountering

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

"TypeError: Cannot read property 'onPlayerScoreChange' of undefined"

即使我正确绑定了我的函数(我认为)

even though I'm binding my functions correctly (I think)

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

'onPlayerScoreChange' Is a method in the Grandparent component which executes when a user hits a '+' or '-' button to change a player's score.

如果有人能解释哪里出了问题,那将非常有帮助,因为我认为我在曾祖父母的构造函数中设置了 this.onPlayerScoreChange = this.onPlayerScoreChange.bind(this).

It would be really helpful if someone could explain what is wrong, because I think I am setting this.onPlayerScoreChange = this.onPlayerScoreChange.bind(this) in the great grandparent's constructor.

父组件:

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>
    )
}}

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

(Component has default props for title)

子组件:

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>
)
}}

孙子组件:

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>
)}}

谢谢!

推荐答案

你使用的地图函数没有绑定 onScoreChange = {this.onPlayerScoreChange},

You have not done binding for the map function where you are using onScoreChange = {this.onPlayerScoreChange},

您可以使用绑定或箭头函数进行绑定

you can either use bind or arrow functions for binding

附:需要绑定,因为 map 函数的上下文与 React 组件上下文不同,因此此函数内的 this 不会引用 React 组件 this,因此您无法访问 React Component 类的属性.

P.S. Binding is needed because the context of the map function is different from the React Component context and hence this inside this function won't be Referring to the React Components this and thus you can't access that properties of the React Component class.

带箭头功能:

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

带绑定

   {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))}

相关文章