React 컴포넌트를 작성할 때 우리는 크게 두 가지 함수 선언 방식을 사용할 수 있습니다: 화살표 함수(Arrow Function)와 일반 함수 선언(Function Declaration). 이 두 방식의 차이점과 각각의 장단점을 자세히 살펴보겠습니다.
1. 문법적 차이
일반 함수 선언 방식
function Greeting(props) {
return <h1>안녕하세요, {props.name}님!</h1>;
}
// 또는 함수 표현식으로도 가능
const Greeting = function(props) {
return <h1>안녕하세요, {props.name}님!</h1>;
};
화살표 함수 방식
const Greeting = (props) => {
return <h1>안녕하세요, {props.name}님!</h1>;
};
// 더 간단한 형태로도 가능
const Greeting = props => <h1>안녕하세요, {props.name}님!</h1>;
2. this 바인딩의 차이
이것은 두 방식의 가장 큰 차이점 중 하나입니다.
일반 함수의 this
function UserProfile() {
this.state = { name: '김철수' };
function handleClick() {
console.log(this.state); // undefined - this가 올바르게 바인딩되지 않음
}
// 해결방법 1: bind 사용
const handleClickBound = handleClick.bind(this);
// 해결방법 2: 화살표 함수로 래핑
const handleClickWrapper = () => {
handleClick();
};
}
화살표 함수의 this
function UserProfile() {
this.state = { name: '김철수' };
// 화살표 함수는 렉시컬 스코프의 this를 유지
const handleClick = () => {
console.log(this.state); // { name: '김철수' } - 정상 작동
};
}
3. 사용 사례별 비교
간단한 프레젠테이션 컴포넌트
// 화살표 함수 - 간결하고 읽기 쉬움
const Button = ({ onClick, children }) => (
<button onClick={onClick}>{children}</button>
);
// 일반 함수 - 더 전통적인 형태
function Button({ onClick, children }) {
return (
<button onClick={onClick}>{children}</button>
);
}
복잡한 로직을 포함한 컴포넌트
// 화살표 함수
const ComplexComponent = () => {
const [count, setCount] = useState(0);
const [name, setName] = useState('');
const handleIncrement = () => {
setCount(prev => prev + 1);
};
const handleNameChange = (e) => {
setName(e.target.value);
};
return (
<div>
<p>카운트: {count}</p>
<button onClick={handleIncrement}>증가</button>
<input value={name} onChange={handleNameChange} />
</div>
);
};
// 일반 함수
function ComplexComponent() {
const [count, setCount] = useState(0);
const [name, setName] = useState('');
function handleIncrement() {
setCount(prev => prev + 1);
}
function handleNameChange(e) {
setName(e.target.value);
}
return (
<div>
<p>카운트: {count}</p>
<button onClick={handleIncrement}>증가</button>
<input value={name} onChange={handleNameChange} />
</div>
);
}
4. 장단점 분석
화살표 함수의 장점
- 간결한 문법으로 코드가 더 깔끔해짐
- this 바인딩 문제를 자동으로 해결
- 암시적 반환(implicit return)을 사용하여 한 줄로 컴포넌트 작성 가능
- 모던 자바스크립트의 트렌드와 일치
화살표 함수의 단점
- prototype 속성이 없어 메서드를 추가할 수 없음
- constructor를 사용할 수 없음
- 가독성이 떨어질 수 있는 경우가 있음 (특히 복잡한 로직의 경우)
일반 함수의 장점
- 더 전통적이고 익숙한 문법
- 프로토타입 메서드 추가 가능
- constructor 사용 가능
- 호이스팅으로 인한 유연성
일반 함수의 단점
- this 바인딩을 수동으로 처리해야 하는 경우가 있음
- 상대적으로 더 장황한 문법
- 화살표 함수에 비해 모던하지 않은 느낌
5. 권장 사용 패턴
화살표 함수를 사용하기 좋은 경우
// 1. 간단한 프레젠테이션 컴포넌트
const Header = ({ title }) => <h1>{title}</h1>;
// 2. 콜백 함수
const List = () => {
const items = ['사과', '바나나', '오렌지'];
return (
<ul>
{items.map(item => <li key={item}>{item}</li>)}
</ul>
);
};
// 3. 이벤트 핸들러
const Form = () => {
const handleSubmit = (e) => {
e.preventDefault();
// 처리 로직
};
return <form onSubmit={handleSubmit}>...</form>;
};
일반 함수를 사용하기 좋은 경우
// 1. 복잡한 클래스 컴포넌트 대체
function ComplexComponent() {
// 여러 메서드와 생명주기 관련 로직
useEffect(function setupComponent() {
// 명확한 함수명으로 인한 가독성 향상
}, []);
function handleComplexLogic() {
// 복잡한 비즈니스 로직
}
return <div>...</div>;
}
// 2. 재사용 가능한 고차 컴포넌트
function withAuth(WrappedComponent) {
return function AuthWrapper(props) {
const isAuthenticated = useAuth();
if (!isAuthenticated) {
return <Navigate to="/login" />;
}
return <WrappedComponent {...props} />;
};
}
결론
- 간단한 컴포넌트나 이벤트 핸들러의 경우 → 화살표 함수
- 복잡한 로직이나 명확한 이름이 필요한 경우 → 일반 함수
- 팀의 컨벤션을 따르는 것이 가장 중요
중요한 것은 일관성 있는 코드 스타일을 유지하는 것입니다. 팀 프로젝트의 경우 팀원들과 합의된 방식을 사용하는 것이 좋습니다.
반응형
'Front-End > React' 카테고리의 다른 글
CRA vs Vite: React 개발 환경의 새로운 패러다임 (0) | 2025.02.10 |
---|---|
React의 useEffect 훅과 사이드 이펙트 알아보기 (1) | 2025.02.08 |
고찰: useState가 배열을 반환하는 이유 (0) | 2025.02.01 |
useReducer 완벽하게 파헤치기 (1) | 2025.01.30 |
useState vs useRef: 언제 무엇을 써야 할까? (0) | 2025.01.29 |