React
의 Component
선언 방식은 클래스형, 함수형 두 가지로 나뉜다.
현재 많은 사람들이 함수형 컴포넌트로 개발을 진행하지만 기존에 클래스형 컴포넌트를 개발중이던 곳도 많을 수 있기 때문에 그 프로젝트의 유지보수를 위해서라도 클래스형 컴포넌트에 대한 개념을 알고 있어야 한다.
두 방식의 일반적인 차이점은 다음과 같다.
클래스형 컴포넌트는 state
와 LifeCycle API
의 사용이 가능하며, 임의 메서드를 정의할 수 있다.
함수형 컴포넌트도 16.8 버전 이후 제공되는 Hook
을 통해 state
와 LifeCycle API
의 사용이 가능하다.
또한 함수형 컴포넌트는 클래스형 컴포넌트보다 선언하기 훨씬 편하며, 메모리 자원을 덜 소비한다.
우선 클래스형 컴포넌트는 선언시 class 키워드가 필요하며, Component를 상속받아야 한다.
또한 화면에 표시하기 위한 render() 메서드가 반드시 필요하다.
import React, { Component } from 'react';
class Home extends Component {
render() {
const text = 'Hello World!!'
return <div>{text}</div>
}
}
export default Home;
반면 함수형 컴포넌트는 함수 자체가 렌더 함수이기 때문에 render() 메서드를 사용하지 않아도 되고, Component를 상속받지 않아도 된다.
즉, 클래스형 컴포넌트보다 좀 더 간결하게 코드를 작성할 수 있다.
import React from 'react';
const Home = () => {
const text = 'Hello World!!'
return <div>{text}</div>
}
export default Home;
클래스형 컴포넌트는 생성자(constructor)
안에서 this.state
를 통해 초기 값을 설정하며, constructor
없이도 초기 값을 설정할 수 있다.
또한 클래스형 컴포넌트의 state
는 객체 형식이며, this.setState
함수로 state
의 값을 변경할 수 있다.
constructor(props){
super(props);
this.state = {
name: 'apple',
price: 20,
};
}
// 생성자 X
class Home extents Component {
state = {
name: 'apple',
price: 20,
}
}
onClick={()=> {
this.setState({ price: price * 10 });
}}
반면 함수형 컴포넌트에서는 useState
로 state
를 핸들링한다.
useState
함수를 호출하면 배열이 반환되는데 첫번째 원소는 state
두번째 원소는 setState
의 역할을 하는 즉, state
를 변경해주는 함수이며, useState
의 파라미터는 state
의 초기값이다.
const App = () => {
const [name, setName] = useState('apple');
const onClickBtn = {()=> {
setName('banana');
}}
}
props
는 컴포넌트의 속성을 설정할 때 사용하는 요소로, 읽기 전용이며 컴포넌트 자체의 props를 수정해서는 안된다.
모든 React
컴포넌트는 자신의 props
를 다룰 때 순수 함수처럼 동작해야 하며, 수정되는 것은 state
만 수정되어야 한다.
클래스형 컴포넌트는 this.props
를 사용하여 props
의 값을 불러온다.
class Home extends Component {
render () {
const { name, price } = this.props;
return (
<div>
과일 {name}의 가격은 {age}원!!
</div>
)
}
}
함수형 컴포넌트는 렌더 함수의 parameter
로 props
를 전달받아 사용한다.
const Home = ({ name, price }) => {
return(
<div>
과일 {name}의 가격은 {age}원!!
</div>
)
}
모든 리액트 컴포넌트에는 라이프사이클이 존재한다.
컴포넌트는 생성(mount) > 업데이트(update) > 제거(unmount)
의 생명주기를 갖으며, 적절한 생명주기에 어떤 작업을 처리해야 하는지 지정해야 불필요한 업데이트를 방지할 수 있다.
클래스형 컴포넌트에서는 LifeCycle API
를 사용하며, 함수형 컴포넌트에서는 Hook
을 사용한다.
클래스형 컴포넌트에서 사용되는 LifeCyle API
는, 컴포넌트가 DOM
위에 생성되기 전과 후의 데이터가 변경되어, 상태를 업데이트하기 전과 후로 실행되는 메서드이다.
함수형 컴포넌트에서 사용되는 Hook
은 React
state
와 생명주기 기능을 연동할 수 있게 해주는 함수이다.
클래스형 컴포넌트에서는 동작하지 않으며, class
없이 React
를 사용할 수 있게 해준다.
클래스형 컴포넌트에서는 함수 선언 시 애로우로 바로 선언이 가능하며, 적용하기 위해선 this
를 붙여야 한다.
onClickBtn = e =>{...}
render() {
return (
<>
<button type='button' onClick={this.onClickBtn}>버튼</button>
</>
)
}
함수형 컴포넌트에서는 const
함수 형태로 선언해야 하며, this
가 필요없다.
const onClickBtn = () => {...}
return (
<>
<button type='button' onClick={onClickBtn}>버튼</button>
</>
)
현재는 리액트 공식 매뉴얼에서도 컴포넌트를 새로 작성할 때 함수형 컴포넌트를 사용하도록 권장하고 있다.
특히 리액트 16.8버전부터는 Hook
을 지원하여, 함수형 컴포넌트의 단점이던 state
와 LifeCyle API의 사용이 불가능하다는 단점을 보완했다.
하지만 리액트의 state
와 생명주기를 이해하기 위한 차원, 그리고 위에서 언급했던 것처럼 유지보수를 진행해야 할 상황이 빈번하게 발생할 수 있다는 점에 있어서 클래스형 컴포넌트의 학습은 필수라고 생각된다.