컴포넌트란?
컴포넌트는 리액트 애플리케이션의 구성 요소입니다. UI를 작은 독립적인 부분으로 나누어 관리할 수 있게 해줍니다.
각 컴포넌트는 자체적인 라이프 사이클을 가지며, 독립적이며 재사용성을 향상시킬 수 있죠.
컴포넌트에는 클래스형 컴포넌트와 함수형 컴포넌트가 있는데 이에 관해 정리해보도록 하겠습니다.
-클래스형 컴포넌트
클래스형 컴포넌트는 더 복잡한 로직이나 상태 관리가 필요한 경우 사용됩니다.
클래스형 컴포넌트는 라이프 사이클 기능( 컴포넌트가 생성되고 제거되는 시점에 호출하여 코드를 실행할 수 있습니다. )과 state 기능을 사용할 수 있습니다. ( state는 컴포넌트의 내부 상태를 관리하기 위해 사용됩니다. 컴포넌트가 렌더링될 때 변경될 수 있는 데이터를 저장하고 관리합니다.)
물론 리액트 버전이 업데이트 됨에 따라 Hooks가 등장하여 현재는 함수형 컴포넌트 또한 해당 기능을 구현할 수 있게 되었습니다.
import React, { Component } from 'react';
class Counter extends Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
}
componentDidMount() {
console.log('컴포넌트가 마운트되었습니다.');
}
componentDidUpdate() {
console.log('컴포넌트가 업데이트되었습니다.');
}
componentWillUnmount() {
console.log('컴포넌트가 언마운트되었습니다.');
}
incrementCount = () => {
this.setState({ count: this.state.count + 1 });
};
render() {
return (
<div>
<p>Count: {this.state.count}</p>
<button onClick={this.incrementCount}>Increment</button>
</div>
);
}
}
export default Counter;
위 코드는 클래스형 컴포넌트에서 주요 라이프 사이클 메서드들을 보여주며, 로그를 출력하고 컴포넌트의 생명주기를 관리하는 예제 코드입니다. 또한 increamentCount 메서드를 호출하여 setState를 통한 상태 업데이트를 진행하는 것을 보여줍니다. this.setState() 메서드를 사용해 상태가 업데이트 되면 컴포넌트가 다시 렌더링됩니다.
- 함수형 컴포넌트
함수형 컴포넌트는 hooks을 통해 라이프 사이클 기능과 state 관리 기능 코드를 짤 수 있습니다. (React 16.8 버전 이후 도입된 Hooks는, 기존 함수형 컴포넌트에서 불가했던 다양한 작업(클래스형 컴포넌트에서만 가능했던 상태관리, 라이프 사이클)가 가능해지도록 했다.)
- Reat 최신 버전에는 다양한 Hook이 제공되고 있으며, 아래는 React에서 제공하는 주요 Hook 몇가지를 정리했습니다.
- useState : 함수형 컴포넌트에서 상태를 관리할 수 있게 해주는 Hook
- useEffect : 컴포넌트가 렌더링 될 때마다 특정 작업(마운트/업데이트/언마운트)을 수행하도록 설정할 수 있는 Hook . 라이플 사이클 메서드와 비슷한 기능을 함.
- useReducer : useState보다 더 다양한 컴포넌트 상태 관리 가능
- useMemo : 함수형 컴포넌트 내부에서 발생하는 연산을 최적화할 수 있게 해주는 Hook
- useCallback : useMemo와 비슷하지만, 이벤트 핸들러 함수를 필요할 때만 생성(함수 재사용시 사용)
- useRef : 함수형 컴포넌트에서 ref를 쉽게 사용할 수 있게 해주는 Hook
. . .
그러면 함수형 컴포넌트에 대한 사용 예시 코드도 함께 살펴봅시다.
import React, { useState, useEffect } from 'react';
const Counter = () => { // ES6 버전 이후 함수 선언 방법
// 상태(state)를 관리하기 위한 useState Hook 사용
// 첫번째 요소는 현재 상태 값, 두번째 요소는 해당 상태 값을 업데이트 하는 함수
const [count, setCount] = useState(0);
// useEffect Hook을 사용하여 라이프사이클 메서드 역할 수행
// 특정 값(count)이 업데이트될 때만 실행
useEffect(() => {
console.log('특정 상황에서만 렌더링.(count 변경시)');
}, [count]);
// 컴포넌트가 언마운트 되기 전이나 업데이트 되기 직전에 작업 수행
useEffect(() => {
// 업데이트 되기 직전에 작업 수행
console.log('컴포넌트가 마운트되었습니다.');
// 언마운트되기 전에 수행(그전까진 수행x)
return () => {
console.log('clean up');
};
}, []); // 빈 배열을 전달하여 컴포넌트가 처음 렌더링될 때만 실행되도록 함
// 버튼 클릭 시 count 상태를 업데이트하는 함수
const incrementCount = () => {
setCount(prevCount => prevCount + 1);
};
return (
<div>
<p>Count: {count}</p>
<button onClick={incrementCount}>Increment</button>
</div>
);
};
export default Counter;
-> 첫 번째 useEffect는 'count'값이 업데이트 될 때마다 실행됩니다. 따라서 'count' 상태가 변경될 때마다 특정 작업을 수행하도록 설정할 수 있는 것입니다.
-> 두 번째 useEffect는 빈 배열을 전달했기 때문에 컴포넌트가 처음 렌더링 될 때만 실행됩니다.(1회만 실행)
clean-up 함수로서 컴포넌트가 언마운트 될 때 'clean up'를 콘솔에 출력합니다.
-> useState 훅을 사용해 count상태를 선언합니다.
-> useState 훅으로부터 반환 된 setCount 상태 설정 함수를 사용해 해당 상태를 업데이트합니다.
위를 통해 컴포넌트의 마운트 시점에서의 작업과 'count' 상태의 업데이트를 다루어 봤습니다.
클래스형 컴포넌트처럼 'this'키워드를 사용하지 않는 것도 확인할 수 있었습니다.
보통 함수형 컴포넌트가 작성이 간단하고 가독성이 좋아 함수형 컴포넌트를 사용하는 것을 선호합니다.
최근에는 클래스형 컴포넌트가 도태되고 Hooks 덕분에 함수형 컴포넌트를 사용하는 추세이긴 하지만, 함수형과 클래스형 컴포넌트를 적절히 혼합하여 유연하게 사용하는 경우가 많아 두 경우 모두 작성할 수 있으면 좋을 것 같습니다.