함수형 컴포넌트 VS 클래스형 컴포넌트
리액트 공식 메뉴얼에서는 함수형 컴포넌트 사용을 권장, 현재 함수형이 표준, 클래스형은 레거시로 본다.
리액트 18버전 이후에는 hook을 본격적으로 지원함으로써 함수형 컴포넌트 + hooks가 성능 최적화에 더 유리함
이후 버전에서도 계속 hook을 고도화 하는 방향으로 업데이트
1. 선언 방식의 차이
함수형 컴포넌트
function Hello() {
return <h1>Hello</h1>;
}
- JSX 반환 → 컴포넌트
- this 없음
클래스형 컴포넌트
class Hello extends React.Component {
render() {
return <h1>Hello</h1>;
}
}
- ES6 class 문법 사용
- 반드시 render() 필요
- this 바인딩 필요해서 문법이 더 복잡함
2. 상태 관리 방식(State)
함수형 컴포넌트
const [count, setCount] = useState(0);
- 여러 개의 상태를 자유롭게 사용 가능
- 비동기 업데이트를 직관적으로 다룸
useEffect(() => {
console.log("mount or update");
return () => console.log("unmount");
}, []);
클래스형 컴포넌트
this.state = { count: 0 };
this.setState({ count: this.state.count + 1 });
- 상태 업데이트 시 객체 병합 방식
- setState 비동기 동작 특성 때문에 버그 발생 확률 높음
3. 라이프사이클(Lifecycle)
함수형 컴포넌트
useEffect(() => {
console.log("mount or update");
return () => console.log("unmount");
}, []);
클래스형 컴포넌트
componentDidMount()
componentDidUpdate()
componentWillUnmount()
shouldComponentUpdate()
4. this 사용여부
함수형 컴포넌트
- this 없음
- props, state 모두 함수 스코프로 확실하게 관리
클래스형 컴포넌트
- this 바인딩 필요
- handleClick을 constructor에서 바인딩하거나
- 화살표 함수로 선언해야 함
좋은 컴포넌트 설계
컴포넌트 설계와 SOLID의 원칙, 리액트 관점에서 SOLID는 정답이 아니며, 객체지향 프로그래밍에서 코드의 재사용성, 유지보수성, 확장성을 높히기 위해서 필요한 다섯가지 설계 원칙
SRP (Single Responsibility Principle) 단일 책임 원칙
비즈니스 관점에서 책임을 분리하는 원칙으로 하나의 컴포넌트에서는 하나의 역할만 해야한다.
컴포넌트가 하나의 역할만 수행할수 있게 설계하여 코드의 가독성과 유지보수성을 높히기 위한 목적
OCP (Open/Closed Principle) 개방 폐쇄 원칙
확장에는 열려있고, 변경에는 닫혀 있어야 한다. === 기존의 코드는 유지하고, 새로운코드로 확장한다.
컴포넌트에 Props속성을 추가해줌으로 새로운 SRP를 적용한 확장
<Button variant="primary" />
<Button variant="danger" />
LSP (Liskov Substitution Principle) 리스코프 치환 원칙
하위타입 객체는 상위 타입 객체에서 가능한 행위를 수행할 수 있어야 한다.
올바른 상속을 위해 자식 객체의 확장이 부모 객체의 방향을 따르도록하는 원칙.
- 컴포넌트가 전달받은 props 계약을 지켜야 한다.
- 부모 컴포넌트를 기반으로 확장한 컴포넌트가 동일하게 동작해야 한다.
리액트에서는 상속성보다는 합성의 개념
https://ko.legacy.reactjs.org/docs/composition-vs-inheritance.html#so-what-about-inheritance
합성 (Composition) vs 상속 (Inheritance) – React
A JavaScript library for building user interfaces
ko.legacy.reactjs.org
props와 합성은 명시적이고 안전한 방법으로 컴포넌트의 모양과 동작을 커스터마이징하는데 필요한 모든 유연성을 제공합니다. 컴포넌트가 원시 타입의 값, React 엘리먼트 혹은 함수 등 어떠한 props도 받을 수 있다는 것을 기억하세요.
ISP (Interface Segregation Principle) 인터페이스 분리 원칙
인터페이스를 사용자에 맞춤형으로 분리해야된다는 설계 원칙
- 컴포넌트에 지나치게 많은 props 넣지 말기
- 복잡한 props는 객체로 묶거나 새로운 컴포넌트로 위임
DIP (Dependency Inversion Principle) 의존 역전 원칙
상위 컴포넌트가 하위 모듈 세부사항에 의존하지 않아야 한다.
- 컴포넌트는 직접 API 호출 같은 구체 구현에 의존하면 안 됨 → custom hook 사용 (SRP)
그럼 유지보수성으로 좋게 설계된 컴포넌트는 실제 성능적으로도 의미가 있을까?
성능에 직접적인 연관 이있는 키워드
- 리렌더링
- 메모리 사용
- DOM 조작
단지 "구조가 좋다" 라는 이유만으로 성능에는 직접적인 연관은 없음,
즉, 설계는 설계이고, 성능은 성능 하지만 유지보수성이 좋다면 성능최적화에 적합한 구조로 개선 가능
컴포넌트를 쪼개는 효과
- 부모 리렌더링이 자식에게 퍼지지 않음
- 메모이제이션 범위가 좁아짐
- 불필요한 상태 공유가 줄어든다
'개발이야기 > React' 카테고리의 다른 글
| ref - DOM 직접 접근 장치 (0) | 2025.11.25 |
|---|---|
| 이벤트 핸들링 (0) | 2025.11.17 |
| render(), virtual DOM, JSX (0) | 2025.11.10 |
| [React] 사진첩 게시판 (0) | 2023.01.04 |
| [React] 이벤트 핸들링 HTML과 비교 (0) | 2022.11.10 |