일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- AuthenticatoinProvide
- Pender
- SpringBoot
- Reduxpender
- UsernamePasswordAuthenticationFilter
- MSA
- preventdefault
- Spring REST Docs
- Crawling
- tasklet
- vue
- Spring Security
- cloud native
- stopPropogation
- REACT
- OpenStack
- MFA
- T-OTP
- gradle
- vuejs
- Flyway
- Spring Batch
- 리액트
- axios
- JavaScript
- openapi3
- Filter
- SWAGGER
- SpringRESTDocs
- cheerio
- Today
- Total
Miracle Morning, LHWN
23. 클래스형 컴포넌트 본문
# 최근에는 클래스형 컴포넌트를 잘 사용하지 않는 추세이지만, 예전에 만들어진 리액트 관련 라이브러리는 Hooks 지원이 안되는 경우도 있고 react-native 관련 라우터 라이브러리 react-native-navigation 의 경우에도 클래스형 컴포넌트를 써야하는 경우가 있다.
따라서 클래스형 컴포넌트도 알고 있으면 도움은 된다.
우선, 함수형 컴포넌트 예시를 보자.
import React from 'react';
function Hello({ color, name, isSpecial }) {
return (
<div style={{ color }}>
{isSpecial && <b>*</b>}
안녕하세요 {name}
</div>
);
}
Hello.defaultProps = {
name: '이름없음'
};
export default Hello;
이를 클래스형 컴포넌트로 변환해보면 아래와 같다.
import React, { Component } from 'react';
class Hello extends Component {
/* defaultProps 설정하는 또 다른 방법
static defaultProps = {
name: '이름없음'
};
*/
render() {
const { color, name, isSpecial } = this.props;
return (
<div style={{ color }}>
{isSpecial && <b>*</b>}
안녕하세요 {name}
</div>
);
}
}
Hello.defaultProps = {
name: '이름없음'
};
export default Hello;
# 클래스형 컴포넌트에는 render() 함수가 반드시 있어야 한다.
# render() 함수에서 렌더링하고 싶은 JSX 를 return 해주면 된다.
# props 를 조회해야 할 때에는 this.props 를 조회하면 된다.
전에 작성했었던 Counter 도 클래스형 컴포넌트로 변경해보자.
import React, { useReducer } from 'react';
function reducer(state, action) {
switch (action.type) {
case 'INCREMENT':
return state + 1;
case 'DECREMENT':
return state - 1;
default:
return state;
}
}
function Counter() {
const [number, dispatch] = useReducer(reducer, 0);
const onIncrease = () => {
dispatch({ type: 'INCREMENT' });
};
const onDecrease = () => {
dispatch({ type: 'DECREMENT' });
};
return (
<div>
<h1>{number}</h1>
<button onClick={onIncrease}>+1</button>
<button onClick={onDecrease}>-1</button>
</div>
);
}
export default Counter;
아래는 클래스형 컴포넌트이다.
import React, { Component } from 'react';
class Counter extends Component {
handleIncrease() {
console.log('increase');
}
handleDecrease() {
console.log('decrease');
}
render() {
return (
<div>
<h1>0</h1>
<button onClick={this.handleIncrease}>+1</button>
<button onClick={this.handleDecrease}>-1</button>
</div>
);
}
}
export default Counter;
onClick 함수를 작성할 때 render() 안에 함수를 구현할 수는 있지만, 일반적으로는 클래스 안에 커스텀 메서드를 선언한다.
※ 클래스 내부에 종속된 함수를 '메서드'라고 부르며, 클래스에서 커스텀 메서드를 만들 때에는 보통 이름을 handle... 으로 짓는다.
<button onClick={this.handleIncrease}>+1</button>
여기서 this 는 컴포넌트 인스턴스를 가리킨다.
handleIncrease() 함수 안에서 this 값을 조회해보면 undefined 가 나오는데, 이 이유는 handleIncrease, handleDecrease 메서드들을 각 button 의 이벤트로 등록하는 과정에서 '메서드 (handleIncrease) <> 컴포넌트 인스턴스 (this)' 관계가 끊겨버린다.
이를 해결하기 위한 방법은 아래 3가지가 있다.
(1) 클래스의 생성자 메서드 constructor 에서 bind 작업을 해주는 것이다.
(2) 커스텀 메서드를 선언할 때 화살표 함수 문법을 사용해서 작성하는 것이다.
(3) onClick 에서 새로운 함수를 만들어서 전달하는 것이다. (비추천)
하나씩 보자.
(1) 클래스의 생성자 메서드 constructor 에서 bind 작업을 해주는 것이다.
import React, { Component } from 'react';
class Counter extends Component {
constructor(props) {
super(props); // 이 클래스가 컴포넌트로서 작동할 수 있도록 해주는 컴포넌트 쪽에 구현되어 있는 생성자 함수를 먼저 실행해주고,
// 우리가 할 작업을 하겠다는 의미
// bind 함수를 사용하면 해당 함수에서 가르킬 this 를 직접 설정해줄 수 있다.
this.handleIncrease = this.handleIncrease.bind(this);
this.handleDecrease = this.handleDecrease.bind(this);
}
handleIncrease() {
console.log('increase');
console.log(this);
}
handleDecrease() {
console.log('decrease');
}
render() {
return (
<div>
<h1>0</h1>
<button onClick={this.handleIncrease}>+1</button>
<button onClick={this.handleDecrease}>-1</button>
</div>
);
}
}
export default Counter;
(2) 커스텀 메서드를 선언할 때 화살표 함수 문법을 사용해서 작성하는 것이다.
class-properties 라는 문법을 사용해서 클래스형 컴포넌트에서 화살표 함수를 사용해서 메서드를 구현한다.
class-properties 문법은 클래스에 특정 속성을 선언할 수 있게 해주는 문법이다.
아직 정식 자바 스크립트 문법이 아니지만 CRA(Create-React-App) 로 만든 프로젝트에는 적용 되어있는 문법이기 때문에 바로 사용할 수 있다.
보통 CRA 로 만든 프로젝트에서 커스텀 메서드를 만들 때 이 방법을 사용한다.
import React, { Component } from 'react';
class Counter extends Component {
handleIncrease = () => {
console.log('increase');
console.log(this);
};
handleDecrease = () => {
console.log('decrease');
};
render() {
return (
<div>
<h1>0</h1>
<button onClick={this.handleIncrease}>+1</button>
<button onClick={this.handleDecrease}>-1</button>
</div>
);
}
}
export default Counter;
(3) onClick 에서 새로운 함수를 만들어서 전달하는 것이다. (비추천)
이 방법은 렌더링 할 때 마다 함수가 새로 만들어지기 때문에 컴포넌트 최적화 시에 매우 까다롭다.
return (
<div>
<h1>0</h1>
<button onClick={() => this.handleIncrease()}>+1</button>
<button onClick={() => this.handleDecrease()}>-1</button>
</div>
);
클래스형 컴포넌트에서 상태 관리해보기
state 라는 것을 사용하는데 constructor 내부에서 this.state 를 설정해주면 된다.
클래스형 컴포넌트에서 state 는 무조건 객체 형태여야 하며, render 메서드에서 state 를 조회하려면 this.state 로 사용하면 된다.
import React, { Component } from 'react';
class Counter extends Component {
constructor(props) {
super(props);
this.state = {
counter: 0
};
}
handleIncrease = () => {
console.log('increase');
console.log(this);
};
handleDecrease = () => {
console.log('decrease');
};
render() {
return (
<div>
<h1>{this.state.counter}</h1>
<button onClick={this.handleIncrease}>+1</button>
<button onClick={this.handleDecrease}>-1</button>
</div>
);
}
}
export default Counter;
근데 우리가 화살표 함수 문법을 사용해서 메서드를 작성할 수 있게 해줬던 class-properties 를 사용하면
굳이 constructor 를 작성하지 않고도 할 수 있다. (CRA 로 만든 프로젝트에서는 이 방법을 가장 많이 사용한다.)
import React, { Component } from 'react';
class Counter extends Component {
state = {
counter: 0
};
handleIncrease = () => {
console.log('increase');
console.log(this);
};
handleDecrease = () => {
console.log('decrease');
};
render() {
return (
<div>
<h1>{this.state.counter}</h1>
<button onClick={this.handleIncrease}>+1</button>
<button onClick={this.handleDecrease}>-1</button>
</div>
);
}
}
export default Counter;
상태 업데이트 해보기
상태를 업데이트 할 때는 this.setState 함수를 사용해서 객체 안에 업데이트 하고 싶은 값을 넣어서 호출해주면 된다.
import React, { Component } from 'react';
class Counter extends Component {
state = {
counter: 0
};
handleIncrease = () => {
this.setState({
counter: this.state.counter + 1
});
};
handleDecrease = () => {
this.setState({
counter: this.state.counter - 1
});
};
}
export default Counter;
이전에 학습했던 useState 에서 함수형 업데이트를 했던 것 처럼 클래스형 컴포넌트에서도 setState 를 사용해서 함수형 업데이트를 할 수 있다.
handleIncrease = () => {
this.setState(state => ({
counter: state.counter + 1
}));
};
handleDecrease = () => {
this.setState(state => ({
counter: state.counter - 1
}));
};
더 자세한 내용은 아래 출처에
출처 : https://react.vlpt.us/basic/24-class-component.html
'IT 기술 > [React] 기본' 카테고리의 다른 글
25. componentDidCatch 로 error 잡아내기 / Sentry 연동 (0) | 2021.05.31 |
---|---|
24. LifeCycle Method (0) | 2021.05.31 |
22. Immer 를 사용한 더 쉬운 불변성 관리! (0) | 2021.05.25 |
21. Context API 를 사용하여 전역 값을 관리하자 (0) | 2021.05.25 |
20. React의 Hooks 총정리! (0) | 2021.05.25 |