수정 방법 - this.setState는 React에서 함수 오류가 아닙니다.

11017 단어 react
반응이 처음이고 클래스 기반 구성 요소를 사용하는 경우 브라우저에서 다음 오류를 볼 수 있습니다.
TypeError: Cannot read properties of undefined (reading 'setState')TypeError: this.setState is not a function
이 오류가 발생하는 이유와 해결 방법이 궁금하십니까? 이 기사에서는 같은 내용을 다룰 것입니다.

오류 복제



다음 코드를 고려하십시오.

import React, { Component } from "react"
import "./App.css"

export default class App extends Component {
  constructor(props) {
    super(props)

    this.state = { counter: 0 }
  }

  updateCounter() {
    this.setState({ counter: this.state.counter + 1 })
  }

  render() {
    return (
      <div className="App">
        <button onClick={this.updateCounter}>
          Clicked {this.state.counter} Times
        </button>
      </div>
    )
  }
}


코드를 빠르게 스캔하면 코드가 완벽할 것이라고 생각할 것입니다. 그러나 코드를 실행하고 버튼을 클릭하면 아무 일도 일어나지 않습니다. 브라우저 콘솔을 확인하면 다음 오류가 표시됩니다.



오류의 원인



이 오류가 발생하는 이유는 Closures in JavaScript이라는 개념 때문입니다. 즉, 함수updateCounter와 클래스App의 범위/컨텍스트가 동일하지 않습니다.
이것은 AppupdateCounter 가 다른 this 를 갖는다는 것을 의미합니다.

우리의 경우 현재 this 인 자체 App 가 있는 함수 내에서 this 클래스의 undefined 에 액세스하려고 합니다. 따라서 오류 Cannot read properties of undefined .

오류를 수정하는 방법



이 문제를 해결하는 방법에는 두 가지가 있습니다.

ES6 화살표 함수 사용



이 문제를 해결하는 가장 쉬운 방법은 아래와 같이 updateCounter 함수를 화살표 함수로 변환하는 것입니다.

import React, { Component } from "react"
import "./App.css"

export default class App extends Component {
  constructor(props) {
    super(props)

    this.state = { counter: 0 }
  }

  updateCounter = () => {
    this.setState({ counter: this.state.counter + 1 })
  }

  render() {
    return (
      <div className="App">
        <button onClick={this.updateCounter}>
          Clicked {this.state.counter} Times
        </button>
      </div>
    )
  }
}


지금 앱을 테스트하면 버튼을 클릭할 때 카운터가 업데이트되는 것을 볼 수 있습니다.

기능을 화살표 기능으로 변경하여 갑자기 문제를 해결한 방법을 물어볼 수 있습니다. this였던 undefined는 어떻게 되었습니까? 음, 화살표 기능에는 자체 기능this이 없습니다! 이들은 선언된 어휘 환경/컨텍스트this를 참조합니다.

우리의 경우 함수 updateCounter는 클래스 App 내부에 정의되어 있으며 클래스의 this를 참조하므로 this.setState가 작동합니다!

이것을 함수에 바인딩



화살표 기능을 사용하지 않으려면(글쎄요, 왜 사용하지 말아야 할 이유가 없군요!) 기존 기능을 사용하여 코드를 수정하면 어떻게 될까요? 자, 방법이 있습니다!

우리는 this 클래스의 bind App를 할 수 있습니다this 기능의 updateCounter.

import React, { Component } from "react"
import "./App.css"

export default class App extends Component {
  constructor(props) {
    super(props)

    this.state = { counter: 0 }

    this.updateCounter = this.updateCounter.bind(this)
  }

  updateCounter() {
    this.setState({ counter: this.state.counter + 1 })
  }

  render() {
    return (
      <div className="App">
        <button onClick={this.updateCounter}>
          Clicked {this.state.counter} Times
        </button>
      </div>
    )
  }
}


구문이 이상하게 보일 수 있지만 클래스를 함수의 구문에 바인딩this하는 것뿐입니다.
this 를 사용하지 않기 때문에 후크가 있는 기능 구성 요소를 사용하는 동안에는 이러한 종류의 문제가 발생하지 않습니다.

좋은 웹페이지 즐겨찾기