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개월 미만으로 짧았습니다.