为什么我收到 "Cannot read property 'state' of undefined" 错误?

Why I'm getting "Cannot read property 'state' of undefined" error?

这是代码:

class QuoteBox extends React.Component {
    constructor(props){
        super(props);

        this.state = {
            quotes: Data,
            current: Data[0]
        }
    }

    setRandomQuote(){
        const index = Math.floor(Math.random() * this.state.quotes.length);
        this.setState({
            current: this.state.quotes[index]
        })
    }

    render(){
        return <div id="quote-box">
            <p id="text">
                {this.state.current.quote}
            </p>
            <h5 id="auther">
                {this.state.current.author}
            </h5>
            <button onClick={this.setRandomQuote} id="new-quote">New Quote</button>
            <a href="" id="tweet-quote">haha</a>
        </div>
    }
};

我收到此错误消息:

TypeError: Cannot read property 'state' of undefined
setRandomQuote

src/Components/QuoteBox/quoteBox.js:15
  12 | }
  13 | 
  14 | setRandomQuote(){
> 15 |     const index = Math.floor(Math.random() * this.state.quotes.length);
     | ^  16 |     this.setState({
  17 |         current: this.state.quotes[index]
  18 |     })

View compiled
▶ 19 stack frames were collapsed.

为什么状态在构造函数中初始化后未定义,我是新手,所以我想确切地了解发生了什么以及为什么。谢谢。

有几种方法可以解决这个问题,class 组件最常用的两种方法是将函数绑定到组件或使用箭头函数。两者的例子如下。

构造函数中的函数绑定:

 constructor(props){
    super(props);

    this.state = {
        quotes: Data,
        current: Data[0]
    }
    this.setRandomQuote = this.setRandomQuote.bind(this)
}

使用箭头函数:(感谢@Linda Paiste)

setRandomQuote = () => {
   const index = Math.floor(Math.random() * this.state.quotes.length);
   this.setState({
       current: this.state.quotes[index]
    })
}

但是,如果您刚刚起步,我强烈建议您使用功能组件,并小心阅读任何使用基于 class 的组件的材料,因为它们可能已过时。

下面是您的 class,重构为功能组件。确保从反应中导入 {useState)。

const QuoteBox = () => {
  const [state, setState] = useState({
    quotes: Data,
    current: Data[0]
  })


  const setRandomQuote = () => {
    const index = Math.floor(Math.random() * state.quotes.length);
    setState({
      ...state,
      current: state.quotes[index]
    })
  }


  return (<div id="quote-box">
    <p id="text">
      {state.current.quote}
    </p>
    <h5 id="auther">
      {state.current.author}
    </h5>
    <button onClick={setRandomQuote} id="new-quote">New Quote</button>
    <a href="" id="tweet-quote">haha</a>
  </div>
  )

};