자바스크립트는 컨스트럭터와 프로토타입을 기반으로 한다.
function Person({ name, age }) {
this.name = name;
this.age = age;
}
Person.prototype.introduce = function () {
return `안녕하세요, 제 이름은 ${this.name}입니다.`;
};
const person = new Person({ name: "윤아준", age: 19 });
ES2015부터 클래스 문법이 추가되었다.
class Person {
// 이전에서 사용하던 생성자 함수는 클래스 안에 `constructor`라는 이름으로 정의합니다.
constructor({ name, age }) {
this.name = name;
this.age = age;
}
// 객체에서 메소드를 정의할 때 사용하던 문법을 그대로 사용하면, 메소드가 자동으로 `Person.prototype`에 저장됩니다.
introduce() {
return `안녕하세요, 제 이름은 ${this.name}입니다.`;
}
}
const person = new Person({ name: "윤아준", age: 19 });
클래스는 기존 생성자 방식보다 엄격하다.
### 클래스형 컴포넌트
클래스형 컴포넌트는
import React, { Component } from "react";
class App extends Component {
render() {
const name = "react";
return <div className="react">{name}</div>;
}
}
export default App;
클래스에서 프롭을 받을 때에는 아래와 같이 사용할 수 있다. (prop-types를 이용해 타입 지정 + static을 이용해 클래스 내부에서 기본값과 타입 지정)
import React, { Component } from "react";
import PropTypes from "prop-types";
class MyComponent extends Component {
static defaultProps = {
name: "기본 이름",
};
static propTypes = {
name: PropTypes.string,
favoriteNumber: PropTypes.number.isRequired,
};
render() {
const { name, favoriteNumber, children } = this.props; // 비구조화 할당
return (
<div>
안녕하세요, 제 이름은 {name}입니다. <br />
children 값은 {children}
입니다.
<br />
제가 좋아하는 숫자는 {favoriteNumber}입니다.
</div>
);
}
}
export default MyComponent;
import React, { Component } from "react";
class Counter extends Component {
constructor(props) {
super(props);
// state의 초깃값 설정하기
this.state = {
number: 0,
};
}
render() {
const { number } = this.state; // state를 조회할 때는 this.state로 조회합니다.
return (
<div>
<h1>{number}</h1>
<button
// onClick을 통해 버튼이 클릭되었을 때 호출할 함수를 지정합니다.
onClick={() => {
// this.setState를 사용하여 state에 새로운 값을 넣을 수 있습니다.
this.setState({ number: number + 1 });
}}
>
+1
</button>
</div>
);
}
}
export default Counter;
alternative class syntax를 지원하는 현재의 리액트 버전에서는 아래와 같이 state 객체를 this에 바인딩하기에 constructor없이도 this.state를 초기화할 수도 있다.
(단 constructor(props)에 사용된 super(props)가 없어져서 this.props에 접근하지 못하는 점은 유의)
import React, { Component } from "react";
class Counter extends Component {
state = {
number: 0,
};
render() {
const { number } = this.state; // state를 조회할 때는 this.state로 조회합니다.
return (
<div>
<h1>{number}</h1>
<button
// onClick을 통해 버튼이 클릭되었을 때 호출할 함수를 지정합니다.
onClick={() => {
// this.setState를 사용하여 state에 새로운 값을 넣을 수 있습니다.
this.setState({ number: number + 1 });
}}
>
+1
</button>
</div>
);
}
}
export default Counter;
static getDerivedStateFromProps(nextProps, prevState) {
if(nextProps.value != = prevState.value) { // 조건에 따라 특정 값 동기화
return { value: nextProps.value };
}
return null; // state를 변경할 필요가 없다면 null을 반환
}
getDerivedStateFromProps()는 props값을 비교하여 state에 적용한다. 컴포넌트가 마운트, 업데이트 될 때 사용
componentDidMount() { ... }는 첫 렌더링 이후 실행된다.
shouldComponentUpdate(nextProps, nextState) { ... } props, state가 변경되었을 때에 업데이트 할 지를 판단한다. this.props, this.state가 현재의 props, state이다. true를 반환하면 업데이트 된다.
getSnapshotBeforeUpdate(prevProps, prevState) {
if(prevState.array != = this.state.array) {
const { scrollTop, scrollHeight } = this.list
return { scrollTop, scrollHeight };
}
}
getSnapshotBeforeUpdate()는 render가 실행되기 전에(업데이트 되기 전에) 실행된다. 기존에 있던 스크롤 값을 새로운 렌더링에 반영하는 등에 사용된다.
componentDidUpdate(prevProps, prevState, snapshot) { ... } 업데이트가 끝난 직후 실행된다. snapshot은 getSnapshotBeforeUpdate에서 반환된 값을 의미한다.
componentWillUnmount() { ... }는 컴포넌트가 DOM에서 제거될 때 실행된다.
componentDidCatch(error, info) {
this.setState({
error: true
});
console.log({ error, info });
}
componentDidCatch()는 에러가 발생했을 때에 실행된다.