TypeError: Cannot read properties of undefined (reading 'state') in react.js (pretty basic code but I couldn't understand any answer in other posts)

huangapple go评论73阅读模式
英文:

TypeError: Cannot read properties of undefined (reading 'state') in react.js (pretty basic code but I couldn't understand any answer in other posts)

问题

我不太理解(开始使用React,关于这个主题的每一个答案似乎都没有太多帮助,因为它有太多东西),因为我尝试使用onMouseOver={console.log(this.state)},它没有任何问题地显示出来。

class GenresInDb extends Component {
    constructor() {
        super()
        this.state = {
            genresList: [],
            genreBg: "",
        }
    };
    componentDidMount() {
        window.fetch('http://localhost:3001/api/genres')
            .then(response => {
                return response.json()
            })
            .then(genres => {
                this.setState({ genresList: genres.data })
            })
            .catch(error => console.log(error))
    }
    changeBg() {
        if (this.state.genreBg === "") {
            this.setState({
                genreBg: "bg-secondary"
            })
        } else {
            this.setState({
                genreBg: ""
            })
        }
    }
    render() {
        return (
            <React.Fragment>
                {/* Genres in DB */}
                <div className="col-lg-6 mb-4">
                    <div className="card shadow mb-4">
                        <div className="card-header py-3">
                            <h6 onMouseOver={this.changeBg} className="m-0 font-weight-bold text-gray-800">Genres in Data Base</h6>
                        </div>
                        <div className={`card-body ${this.state.genreBg}`}>
                            <div className="row">
                                {this.state.genresList.map((genre, index) => {
                                    return <Genre {...genre} key={index} />
                                })}
                            </div>
                        </div>
                    </div>
                </div>
            </React.Fragment>
        )
    }
}

我期望当我用鼠标悬停时,使用setState更改背景颜色,但显然我的方法内的this.state是未定义的。

英文:

I don't really understand (getting started on react and every answer on this topic really didn't help for it had too many things) because I tried onMouseOver={console.log(this.state)} and it showed it without any problem.

class GenresInDb extends Component {
constructor() {
super()
this.state = {
genresList: [],
genreBg: &quot;&quot;,
}
};
componentDidMount() {
window.fetch(&#39;http://localhost:3001/api/genres&#39;)
.then(response =&gt; {
return response.json()
})
.then(genres =&gt; {
this.setState({ genresList: genres.data })
})
.catch(error =&gt; console.log(error))
}
changeBg() {
if(this.state.genreBg === &quot;&quot;){
this.setState({
genreBg: &quot;bg-secondary&quot;
})
} else {
this.setState({
genreBg: &quot;&quot;
})
}
}
render() {
return (
&lt;React.Fragment&gt;
{/*&lt;!-- Categories in DB --&gt;*/}
&lt;div className=&quot;col-lg-6 mb-4&quot;&gt;
&lt;div className=&quot;card shadow mb-4&quot;&gt;
&lt;div className=&quot;card-header py-3&quot;&gt;
&lt;h6 onMouseOver={this.changeBg} className=&quot;m-0 font-weight-bold text-gray-800&quot;&gt;Genres in Data Base&lt;/h6&gt;
&lt;/div&gt;
&lt;div className={`card-body ${this.state.genreBg}`}&gt;
&lt;div className=&quot;row&quot;&gt;
{this.state.genresList.map((genre, index) =&gt; {
return &lt;Genre {...genre} key={index} /&gt;
})}
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/React.Fragment&gt;
)
}
}

I expected the background color to change when I hovered with the mouse use the setState yet apparently my this.state inside my method is undefined.

答案1

得分: 0

您的问题来自changeBg()函数中的this.state.genreBg

这是因为changeBg()函数作用域中的this关键字(1)与GenresInDb()函数作用域中的其他this关键字(2)不相同(<GenresInDb>组件中的this)。

为什么(1)和(2)不相同?

“this”关键字通常引用JavaScript元素,取决于其使用的范围或上下文。

有全局this范围和函数this范围。

...在使用严格模式时,函数中的“this”将引用其显式值,如果未明确设置“this”,则“this”将为undefined

也许您正在使用React.StrictMode,因此changeBg()函数中的thisundefined

您可以参考此文章以更深入了解“this”关键字。对于新手来说,可能有点模糊。


回到您的问题,要解决这个问题,您只需要将函数改为箭头函数

changeBg = () => {
    if(this.state.genreBg === ""){
        this.setState({
            genreBg: "bg-secondary"
        })
    } else {
        this.setState({
            genreBg: ""
        })
    }
}
英文:

Your issue came from this.state.genreBg in function changeBg().

This is because the this keyword (1) in scope of function changeBg() is not the same as those other this keywords (2) in scope of function GenresInDb() (the &lt;GenresInDb&gt; component).

Why (1) and (2) are not the same?

> The ‘this’ keyword typically references a JavaScript element depending on the scope or context of its use.

There are Global ‘this’ scope and Function ‘this’ scope.

> ...When using strict mode, "this" in a function will refer to it’s explicit value, and if "this" hasn’t been explicitly set then "this" will be undefined.

And maybe you're in React.StrictMode, so that the this in function changeBg() are undefined.

You can refer to this post to understand more about this keyword. It's quite fuzzy for newbies to understand.


Back to your problem, to solve that, you only need to change function into arrow function.

changeBg = () =&gt; {
if(this.state.genreBg === &quot;&quot;){
this.setState({
genreBg: &quot;bg-secondary&quot;
})
} else {
this.setState({
genreBg: &quot;&quot;
})
}
}

huangapple
  • 本文由 发表于 2023年3月3日 22:14:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/75628183.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定