지금은 함수 컴포넌트가 메인이지만.. 함수 컴포넌트가 나오기 전부터 16.8버전까지 클래스 컴포넌트를 기본 컴포넌트로 사용했다고 한다.
함수 컴포넌트가 나오고 나서도 클래스 컴포넌트가 쓰였었는데, 함수 컴포넌트는 리액트 훅이 나오기 전까지 상태관리(state)를 할 수 없었기 때문이다.
후에 리액트 훅이 나오면서 함수 컴포넌트에서 state를 사용할 수 있게 되었고, 기본 컴포넌트도 사용하기 더 쉬운 함수 컴포넌트로 옮겨졌다고 한다.(훅이 나온게 16.8버전부터이다.)
지금 공부하고 있는 책에 클래스 컴포넌트를 설명하는 파트가 있다.
책에서는 다음과 같이 설명하고 있다.
리액트의 버전 16.8이 나오기 전까지 긴 시간 동안 이미 많은 웹 애플리케이션과 리액트와 관련된 라이브러리들이 클래스 컴포넌트로 개발되어 왔기 때문에 우리는 클래스 컴포넌트를 다루는 방법에 대해서도 이해하고 있어야 한다.
import React,{ Component } from 'react';
export class 컴포넌트명 extends Component {
로직~
}
interface Props {}
interface State {}
export class 컴포넌트명 extends Component<Props, State> {
로직~~
}
(인터페이스 명이 반드시 Props와 State일 필요 없다.. 마음대로 지으면 된다)
export class 컴포넌트명 extends Component {
render(
로직..
return(jsx코드)
)
}
export class 컴포넌트명 extends Component<Props> {
render(
const {
props1,
props2 = 'default value',
props3,
} = this.props;
로직~~~
return(jsx코드)
)
}
interface Props {}
interface State {
readonly state1: string;
readonly state2: string[];
}
export class 컴포넌트명 extends Component<Props, State> {
로직!
}
constructor(props: Props) {
super(props);
this.state = { state1: '', state2: [] };
}
//함수 컴포넌트의 경우
const [state, setState] = useState();
//클래스 컴포넌트의 경우
this.setState({state명: 변경값})
private addToDo = (): void => {
const { toDo, toDoList } = this.state;
if (toDo) {
this.setState({ toDo: '', toDoList: [...toDoList, toDo] });
}
};
<button onClick={this.함수명}/>
constructor(props: Props) {
super(props);
this.state = { toDo: '', toDoList: [] };
}
export class 컴포넌트명 extends Component {
render(
로직..
return(jsx코드)
)
}
static getDerivedStateFromProps(nextProps: Props, prevState: State) {
console.log('getDerivedStateFromProps');
return null;
}
componentDidMount() {
console.log('componentDidMount');
}
shouldComponentUpdate(nextProps: Props, nextState: State){
console.log('shouldComponentUpdate');
return nextProps.id !== this.props.id;
//리렌더링 허용
//return true;
//리렌더링 방지
//return false;
}
리렌더링을 방지하는 이유 : 화면 렌더링을 최적화한다.
- 리렌더링은 리액트에서 비용이 가장 많이 든다.
- 불필요한 리렌더링을 방지하여 성능을 향상시킬 수 있다.
getSnapshotBeforeUpdate(prevProps: Props, prevState: State) {
console.log('getSnapshotBeforeUpdate');
return {
testData: true,
};
}
import { IScriptSnapshot } from 'typescript';
componentDidUpdate(prevProps: Props, prevState: State, snapshot: IScriptSnapshot) {
console.log('componentDidUpdate');
}
componentWillUnmount() {
console.log('componentWillUnmount');
}
componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
// this.setState({error: true});
}
render함수는 필수이고, 나머지는 생략 가능하다.
블로그에 정리하면서 느낀 점은.. 함수형 컴포넌트가 훨씬 이해하기 쉽다!
클래스형 컴포넌트를 사용해서 코드를 짠다고 생각하기 보다는 어떻게 돌아가고, 함수들이 어떤 기능을 하는지 먼저 익혀야 할 것 같다.