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

Posted

技术标签:

【中文标题】使用地图时反应\'无法读取未定义的属性\'【英文标题】: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>
)

谢谢!

【问题讨论】:

忘记在地图中绑定,使用这个:this.state.initialPlayers.map((player, index) =&gt; 谢谢!现在很有意义 "this" is undefined inside map function Reactjs的可能重复 【参考方案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)

【讨论】:

以上是关于使用地图时反应'无法读取未定义的属性'的主要内容,如果未能解决你的问题,请参考以下文章

React Redux TypeError:无法读取未定义的属性“地图”

TypeError:从 API 获取时无法读取未定义的属性(读取“地图”)

无法在页面刷新时读取未定义反应路由器的属性

ReactJS TypeError:无法读取未定义的属性(读取“地图”)

反应 - 未捕获的类型错误:无法读取未定义的属性“toLowerCase”

错误:无法读取未定义的属性“地图”