【问题标题】:React 'cannot read property of undefined' when using map使用地图时反应'无法读取未定义的属性'
【发布时间】:2017-12-14 02:23:02
【问题描述】:

我正在从 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>
    )
}}

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

子组件:

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

谢谢!

【问题讨论】:

标签: javascript reactjs frontend


【解决方案1】:

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

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

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

带箭头功能:

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

【讨论】:

    【解决方案2】:

    也可以通过将第二个参数作为 this 传递给 map 函数来完成,因为 onClick 事件使用本地 this 的 map 函数,此处未定义,this 当前指的是全局对象。

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

    【讨论】:

      【解决方案3】:

      有时这很容易,这完全取决于你如何声明你的循环

      example 如果您尝试执行类似 var.map(function(example, index) {}

      的操作,则会收到此错误

      但是如果你用这个在地图中调用新函数

      this.sate.articles.map(list => 
      {<a onClick={() => this.myNewfunction()}>{list.title}</a>)}
      

      第二个循环会让你摆脱未定义的错误

      别忘了绑定你的新函数

      【讨论】:

        【解决方案4】:

        //这应该在map函数之前声明

        const thObj = this;

        this.sate.articles.map(list => { thObj.myNewfunction()}>{list.title})}

        【讨论】:

          猜你喜欢
          • 2022-01-25
          • 2018-12-18
          • 1970-01-01
          • 2021-12-02
          • 2020-09-23
          • 2019-04-26
          • 1970-01-01
          • 1970-01-01
          • 2019-09-04
          相关资源
          最近更新 更多