Computer >> 컴퓨터 >  >> 프로그래밍 >> JavaScript

React 오류 해결: 'setState' 속성을 읽을 수 없습니다(undefined) 에러 고치는 방법

React 컴포넌트를 처음 작성하기 시작하면 여러 가지 오류를 만나게 됩니다. 그중 대표적인 것이 "Cannot read property 'setState' of undefined"와 "this.setState is not a function" 오류입니다. 이 글에서는 이러한 오류가 발생하는 원인과 함께, 오류를 해결하는 두 가지 방법을 살펴보겠습니다.

오류는 왜 발생할까?

이 오류들은 React 컴포넌트에서 호출하는 메서드가 올바르게 바인딩(bind)되지 않았기 때문에 발생합니다. 다음은 오류가 발생하는 코드 예시입니다(React 컴포넌트가 올바르게 설정되어 있다고 가정합니다):

import React from "react";
import "./styles.css";
 
class App extends React.Component {
 constructor(props) {
   super(props);
   this.state = {
     input: ""
   };
 }
 
 handleChange(e) {
   this.setState({[e.target.name]: e.target.value})
 }
 render() {
   console.log(this.state)
   return (
     <div className="App">
       <h1>Sample React Application</h1>
       <input name="input" onChange={this.handleChange} value={this.state.input} type="text" placeholder="Type here..."/>
       <input type="submit" />
     </div>
   );
 }
}
 
export default App;

언뜻 보면 코드에 문제가 없어 보이지만, 자세히 살펴보면 handleChange 메서드가 App 클래스에 바인딩되어 있지 않습니다. 그 결과 "this" 키워드가 이 경우 Window 객체를 참조하게 됩니다. 이를 직접 확인해 보기 위해 handleChange 메서드의 첫 줄과 render 메서드의 첫 줄에 각각 console.log(this)를 추가해 보겠습니다:

handleChange(e) {
   console.log(this, "change")
   this.setState({[e.target.name]: e.target.value})
 }
render() {
   console.log(this, "render")
   return (
     <div className="App">
       <h1>Sample React Application</h1>
       <input name="input" onChange={this.handleChange} value={this.state.input} type="text" placeholder="Type here..."/>
       <input type="submit" />
     </div>
   );
 }

애플리케이션을 로드한 후 콘솔을 확인해 보면 render 시점의 "this" 키워드는 App 컴포넌트를 참조합니다. 하지만 입력 필드에 값을 입력해 보면 화면에 오류가 나타나고, 콘솔을 확인하면 이때의 "this" 키워드는 Window 객체를 참조하고 있음을 알 수 있습니다. 이 문제를 해결하는 방법은 두 가지가 있습니다.

1. 메서드를 바인딩하기

constructor 내부에서 state 객체 뒤에 다음 코드를 추가합니다:

   this.handleChange = this.handleChange.bind(this);

이 한 줄은 "this" 키워드를 handleChange 메서드에 바인딩하여, handleChange를 호출할 때 명시적으로 App 컴포넌트를 참조하도록 만듭니다. 바인딩하지 않으면 메서드는 자신이 동작해야 할 컴포넌트를 인식하지 못합니다.

2. ES6 화살표 함수 사용하기

ES6의 화살표 함수(arrow function) 문법을 사용하는 방법도 있습니다. 화살표 함수는 "this" 키워드를 해당 메서드에 자동으로 바인딩하므로, constructor에서 별도로 바인딩할 필요가 없습니다:

handleChange = (e) => {
   this.setState({[e.target.name]: e.target.value})
 }

이것으로 끝입니다! React에서 클래스 컴포넌트 구조를 사용할 때 발생하는 "this.setState"가 "undefined"이거나 "함수가 아니다"라는 오류를 해결하는 방법을 알아보았습니다. 앞으로 이런 오류를 사전에 예방하고 싶다면, 클래스 컴포넌트 대신 React Hooks를 활용한 함수형 컴포넌트로 리팩토링하는 것도 좋은 선택입니다!

부트캠프 참가자의 81%는 수료 후 기술 분야 취업 전망에 대해 더 큰 자신감을 느꼈다고 답했습니다. 지금 자신에게 맞는 부트캠프를 찾아보세요.

부트캠프 수료생의 평균 커리어 전환 기간은 부트캠프 시작부터 첫 직장 취득까지 6개월 미만으로 짧았습니다.