벨로퍼트 리액트 - 24. 클래스형 컴포넌트
클래스형 컴포넌트 : 지금은 잘 상용하지 않으나 유지보수와 지원이 되지 않는 경우를 대비해 알아둘 필요 있음
클래스형 컴포넌트 사용방법
import React, { Component } from 'react';
class Hello extends Component {
render() {
const { color, name, isSpecial } = this.props;
return (
<div style={{ color }}>
{isSpecial && <b>*</b>}
안녕하세요 { name }
</div>
);
}
}
Hello.defaultProps = {
name: '이름없음'
}
export default Hello;
render() : 필수! 이 메서드에서 렌더링하고싶은 JSX를 반환하면 된다.
this.props : props를 조회해야할때 사용
defaultProps : props의 값이 설정되지 않았을때 기본으로 설정되는 값. 함수형 컴포넌트에서 사용할때와 같다. 또는 아래처럼 클래스 내부에 static 으로 선언할 수도 있다.
import React, { Component } from 'react';
class Hello extends Component {
static defaultProps = {
name: '이름없음'
};
render() {
const { color, name, isSpecial } = this.props;
return (
<div style={{ color }}>
{isSpecial && <b>*</b>}
안녕하세요 {name}
</div>
);
}
}
export default Hello;
커스텀 메서드 만들기
// 함수형 => 컴포넌트 안에 선언
const onIncrease = () => {
dispatch({ type: 'INCREMENT' });
};
// 클래스형 => 클래스 안에 커스텀 메서드 선언함!
class Counter extends Component {
handleIncrease() {
console.log('increase');
}
handleDecrease() {
console.log('decrease');
}
...
}
this.setState : 상태 업데이트. this는 컴포넌트 인스턴스를 가리켜야 하나 위의 코드로는 this를 조회하면 컴포넌트 인스턴스를 가리키지 않는다.
⇒ 커스텀 메서드를 각 button의 이벤트로 등록하는 과정에서 메서드와 컴포넌트 인스턴스간의 관계가 끊기기 때문.
해결 방법 1
클래스의 생성자 메서드 constructor에서 bind 작업하기
class Counter extends Component {
constructor(props) {
super(props);
this.handleIncrease = this.handleIncrease.bind(this);
this.handleDecrease = this.handleDecrease.bind(this);
}
...
}
bind를 사용하면 해당 함수에서 가리킬 this를 직접 설정할 수 있다.
constructor에서는 props를 파라미터로 받아오고 super(props)를 호출해야하는데, 이것은 이 클래스가 컴포넌트로서 작동할 수 있게 해주는 Component 쪽에 구현되어있는 생성자 함수를 먼저 실행하고 할 작업을 하겠다는 뜻.
해결 방법 2
커스텀 메서드를 선언할때 화살표 함수 문법을 사용해서 작성하기
class Counter extends Component {
handleIncrease = () => {
console.log('increase');
console.log(this);
};
handleDecrease = () => {
console.log('decrease');
};
...
}
해결 방법 3
onClick에서 새로운 함수를 만들어서 전달하는 것. 단 렌더링할때마다 함수가 새로 만들어지기 때문에 컴포넌트 최적화시 까다로워짐
return (
<div>
<h1>0</h1>
<button onClick={() => this.handleIncrease()}>+1</button>
<button onClick={() => this.handleDecrease()}>-1</button>
</div>
);
상태 선언하기
state : 상태 관리할때 사용. constructor 내부에 this.state 설정
class Counter extends Component {
constructor(props) {
super(props);
this.state = {
counter: 0
};
}
...
render() {
return (
<div>
<h1>{this.state.counter}</h1>
...
</div>
);
}
}
클래스형 컴포넌트의 state 는 무조건 객체형태여야함!!
state 조회시에는 this.state 조회
상태 업데이트하기
this.setState 함수 사용
class Counter extends Component {
state = {
counter: 0
};
handleIncrease = () => {
this.setState({
counter: this.state.counter + 1
});
};
handleDecrease = () => {
this.setState({
counter: this.state.counter - 1
});
};
...
}
벨로퍼트 리액트 - 25. LifeCycle Method
- LifeCycle Method : 생명주기 메서드. 컴포넌트가 브라우저 상에 나타나고, 업데이트 되고, 사라질때 호출되는 메서드. 클래스형 컴포넌트에서만 사용 가능함. (useEffect와 약간 비슷함)
마운트
- constructor : 컴포넌트의 생성자 메서드. 컴포넌트가 만들어지면 가장 먼저 실행
- getDerivedStateFromProps : props로 받아온 것을 state에 넣어주고 싶을때. 컴포넌트가 처음 렌더링 되기 전, 이후 리렌더링 되기 전에 매번 실행된다. 앞에 static을 필요로 하고 이 안에서는 this를 조회할 수 없다. 특정 객체를 반환하게 될시 해당 객체 안의 내용들이 컴포넌트의 state로 설정이 된다. 반면 null을 반환하면 아무일도 생기지 않는다.
- render : 컴포넌트를 렌더링하는 메서드
- componentDidMount : 컴포넌트의 첫번째 렌더링이 마치고 나면 호출되는 메서드. 호출시점에는 컴포넌트들이 화면에 나타난 상태이다. DOM을 사용해야하는 외부 라이브러리 연동을 하거나 해당 컴포넌트에서 필요로 하는 데이터를 요청하기 위해 axios, fetch 등을 통해 ajax 요청을 하거나 DOM의 속성을 읽거나 직접 변경하는 작업을 진행한다.
업데이트
- getDerivedStateFromProps
- shouldComponentUpdate : 컴포넌트가 리렌덜이 할지 말지 결정. 최적화할때 사용. (React.memo 와 비슷함)
- render
- getSnapshotBeforeUpdate : 컴포넌트에 변화가 일어나기 직전의 DOM 상태를 가져와서 특정값을 반환하게 되면 그 다음 발생하는 componentDidUpdate 함수에서 받아와서 사용할수있다. DOM에 변화가 반영되기 직전에 DOM의 속성을 확인하고 싶을때 사용하면 된다.
- componentDidUpate : 리렌더링이 마치고 화면에 변화가 모두 반영되고 난 뒤 호출되는 메서드. 3번째 파라미터로 getSnapshotBeforeUpdate에서 반환한 값을 조회할 수 있다.
언마운트
- componentWillUnmount : 컴포넌트가 화면에서 사라지기 직전에 호출. DOM에 직접 등록했었던 이벤트를 제거하고 만약 setTimeout을 건것이 있다면 clearTimeout으로 제거한다. 추가적으로 외부 라이브러리를 사용한게 잇고 해당 라이브러리에 dispose 기능이 있다면 여기서 호출한다.