함수형 컴포넌트는 상태와 생명 주기 메서드를 가진 클래스형 컴포넌트와 달리 순수 함수로 UI를 정의한다.
이러한 컴포넌트는 불변성을 유지하며 코드를 최소화한다.
import React from 'react';
// 함수형 컴포넌트 정의
const Greeting = ({ name }) => {
return <h1>Hello, {name}!</h1>;
};
// 함수형 컴포넌트 사용
const App = () => {
return (
<div>
<Greeting name="Alice" />
<Greeting name="Bob" />
</div>
);
};
export default App;
불변성(Immutability)
함수형 클래스는 불변성을 유지한다. 이는 객체의 상태가 생성된 이후에 변경되지 않음을 의미한다.
상태가 변경되지 않기 때문에, 객체를 여러 스레드에서 동시에 안전하게 사용할 수 있다.
함수형 메서드
함수형 클래스는 상태를 변경하지 않는 메서드를 포함한다.
이러한 메서드는 주어진 입력에 대해 일정한 출력을 제공하며, 객체의 상태를 변경하지 않는다.
하지만 상태를 가지지 않으므로, 상태를 관리하기 위해 여러 개의 함수형 컴포넌트를 사용할 경우 렌더링 성능에 영향을 준다. 복잡한 상태를 관리해야 하는 경우, 상태 관리 라이브러리(예: Redux)와 결합하여 복잡도가 증가하는 단점이 있다.
데이터 중심 설계
함수형 클래스는 종종 데이터를 중심으로 설계되며, 데이터의 변환이나 조작을 함수형 프로그래밍 패턴에 맞게 처리한다.
이러한 클래스는 사이드 이펙트(side effect)가 없고, 입력값이 동일하면 항상 동일한 출력을 보장한다.
장점
- 스레드 안전성: 불변성을 유지하므로 다중 스레드 환경에서 안전하게 사용할 수 있다.
- 디버깅 용이성: 상태 변경이 없으므로 프로그램의 동작을 이해하고 디버깅하기가 쉽다.
- 예측 가능한 동작: 함수형 메서드는 입력이 동일하면 항상 동일한 출력을 보장하므로 예측 가능한 동작을 제공한다.
단점
- 성능 문제: 객체를 변경할 때마다 새로운 객체를 생성하므로 메모리 사용량이 증가할 수 있다.
- 복잡성 증가: 불변성과 함수형 프로그래밍 패턴을 강제하면 코드가 복잡해진다.
컴포넌트
컴포넌트는 독립적으로 개발, 배포, 유지보수할 수 있는 모듈이다.
각 컴포넌트는 특정 기능이나 서비스를 제공하며, 시스템 내에서 명확한 역할을 가지고 있다.
예를 들어, 웹 애플리케이션에서 사용자 인터페이스를 구성하는 버튼, 폼, 모달 등이 각각의 컴포넌트로 구현된다.
모듈
특정 기능이나 책임을 가진 코드 집합으로, 독립적으로 작동하고 재사용되는 코드의 단위이다.
//프로젝트 구조
│
├── /src
│ ├── /components
│ │ ├── Button.js
│ │ ├── Header.js
│ │ └── Footer.js
│ ├── /utils
│ │ └── formatDate.js
│ ├── /styles
│ │ └── App.css
│ ├── App.js
│ ├── index.js
│ └── index.css
│
└── package.json
package com.example.utils;
// src/components/Button.js
import React from 'react';
import './Button.css'; // 모듈화된 스타일
const Button = ({ label, onClick }) => {
return (
<button className="button" onClick={onClick}>
{label}
</button>
);
};
export default Button;
// src/components/Header.js
import React from 'react';
import './Header.css'; // 모듈화된 스타일
const Header = () => {
return (
<header className="header">
<h1>My Application</h1>
</header>
);
};
export default Header;
// src/components/Footer.js
import React from 'react';
import './Footer.css'; // 모듈화된 스타일
const Footer = () => {
return (
<footer className="footer">
<p>© 2024 My Application</p>
</footer>
);
};
export default Footer;
App.js
// src/App.js
import React from 'react';
import Header from './components/Header';
import Footer from './components/Footer';
import Button from './components/Button';
import formatDate from './utils/formatDate';
import './styles/App.css'; // 모듈화된 스타일
const App = () => {
const handleClick = () => {
alert(`Current Date: ${formatDate(new Date())}`);
};
return (
<div className="app">
<Header />
<main>
<h2>Welcome to My App</h2>
<Button label="Show Date" onClick={handleClick} />
</main>
<Footer />
</div>
);
};
export default App;
index.js는 React와 ReactDOM 모듈을 가져와 HTML 요소에 렌더링한다.
HTML 요소는 index.html 파일에 정의된 <div id="root"></div>와 같은 컨테이너와 같다.
// src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import './index.css'; // 전역 스타일
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
캡슐화
컴포넌트는 내부 구현을 외부에 노출하지 않고, 필요한 인터페이스만 공개한다.
이를 통해 내부 구현 세부 사항을 숨기고, 외부에서 제공하는 서비스나 기능만을 사용한다.
예를 들어, 컴포넌트가 내부 상태를 유지하더라도, 외부는 컴포넌트가 제공하는 메서드만 사용하여 상호작용한다.
재사용성
컴포넌트는 재사용 가능한 단위로 설계되어, 여러 위치에서 동일한 컴포넌트를 사용할 수 있다.
이는 코드 중복을 줄이고, 유지보수를 용이하게 만든다.
예를 들어, 버튼 컴포넌트를 여러 페이지에서 재사용함으로써 일관된 디자인을 유지할 수 있다.
확장성
컴포넌트 기반 설계는 시스템을 쉽게 확장할 수 있도록 지원한다.
새로운 기능을 추가하거나 기존 기능을 수정할 때, 전체 시스템에 미치는 영향을 최소화할 수 있다.
새로운 기능을 추가하기 위해 기존 컴포넌트를 수정하거나 새로운 컴포넌트를 추가할 수 있다.
재사용성 | 컴포넌트는 독립적으로 설계되므로 여러 애플리케이션에서 재사용할 수 있다. |
유지보수 용이 | 컴포넌트 단위로 수정할 수 있어, 시스템 전체를 수정하지 않고도 특정 기능을 변경할 수 있다. |
모듈화 | 시스템을 작은 구성요소로 나누어 개발하므로, 복잡성을 줄이고 이해하기 쉽다. |
독립적 개발 및 테스트 | 각 컴포넌트는 독립적으로 개발 및 테스트할 수 있어, 전체 시스템에 영향을 미치지 않는다. |
의존성 관리 | 컴포넌트 간의 의존성을 명확히 정의하고 관리할 수 있어, 시스템의 안정성을 높일 수 있다. |
컴포넌트 간 통신 복잡성 | 컴포넌트 간의 데이터 교환 및 통신이 복잡할 수 있으며, 이를 관리하기 위한 추가적인 설계가 필요하다. |
성능 문제 | 컴포넌트 간의 상호작용이 많을 경우, 성능 저하가 발생할 수 있으며 이는 최적화가 필요하다. |
초기 설계 및 구조 설계의 어려움 | 컴포넌트를 효과적으로 설계하고 구조를 정의하는 것이 어려울 수 있으며 잘못 설계된 경우 유지보수에 문제를 일으킬 수 있다. |
버전 관리의 어려움 | 컴포넌트가 서로 다른 버전을 사용할 경우, 호환성 문제를 일으킬 수 있다. |
테스트 복잡성 | 각 컴포넌트가 독립적으로 테스트되지만, 전체 시스템의 통합 테스트는 복잡할 수 있다. |
'CS > JAVASCRIPT' 카테고리의 다른 글
React와 ReactDOM (0) | 2024.08.14 |
---|---|
AJAX(Asynchronous JavaScript and XML) (0) | 2024.08.14 |
REST API (0) | 2024.07.18 |
JSON (0) | 2024.06.28 |
var, let, const (0) | 2024.06.28 |