리액트에 대해 면접 질문으로 가장 많이 나오는 질문은 아마 클래스형 컴포넌트와 함수형 컴포넌트의 차이점입니다. 클래스형 컴포넌트는 전통적인 컴포넌트 작성 방식으로,
생명주기 메서드
를 포함한 더 많은 기능을 제공합니다. 그러나,this
를 사용해야 하고, 코드도 더 복잡합니다. 반면, 함수형 컴포넌트는 간결하고 이해하기 쉬운 구조입니다. 최근React Hooks
도입으로 함수형 컴포넌트에서도 상태 관리와 생명주기 메서드의 기능을 활용할 수 있습니다.
현재 컨텍스트를 참조하는 키워드로 컴포넌트의
state
나props
에 접근하기 위해 씁니다. 클래스 안에서 선언된this
는 일반적으로 그 클래스의 인스턴스를 가리킵니다.this.state
를 통해 컴포넌트의 상태를 참조하고 변경할 수 있으며,this.props
를 통해부모컴포넌트
로부터 받은 속성에 접근할 수 있습니다.
JavaScript에서
this
는 함수가 호출되는 방식에 따라 그 값이 바뀔 수 있기 때문에 주의가 필요합니다. 특히 이벤트 핸들러나 콜백 함수에서this
가 예상치 못한 객체를 가리키는 문제가 종종 발생합니다. 이를 해결하기 위해, React 클래스 컴포넌트에서는 이벤트 핸들러를 생성자에서this
와 바인드하거나, 화살표 함수로 이벤트 핸들러를 선언하는 방법을 사용합니다.
// 1. 생성자에서 직접 바인딩하는 방법:
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = { message: 'Hello' };
// 이벤트 핸들러를 현재 인스턴스와 바인딩
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
alert(this.state.message);
}
render() {
return <button onClick={this.handleClick}>Click me</button>;
}
}
// 2. 화살표 함수를 사용하는 방법:
class MyComponent extends React.Component {
state = { message: 'Hello' };
// 화살표 함수를 사용하여 이벤트 핸들러를 정의
handleClick = () => {
alert(this.state.message);
}
render() {
return <button onClick={this.handleClick}>Click me</button>;
}
}
두 번째 방법에서는 화살표 함수의 특성을 이용하여
this
를 자동으로binding
하고 있습니다. 화살표 함수는 자신이 선언된 컨텍스트의this
를 가리키므로 별도로 바인딩 과정을 거치지 않아도 됩니다. 이벤트 핸들러 내부에서this
를 사용하면 항상 올바른 컴포넌트 인스턴스를 가리키게 됩니다.
React의 생명주기 메서드는 컴포넌트가 페이지에 나타나거나, 업데이트되거나, 사라질 때 발생하는 일련의 이벤트를 처리하는 메서드입니다. 대표적인 메서드로는
componentDidMount
,componentDidUpdate
,componentWillUnmount
등이 있습니다.
클래스형 컴포넌트에서는 이 메서드들을 직접적으로 클래스 내부에 정의해서 사용합니다. 만약, 컴포넌트가 처음 화면에 렌더링될 때 API 요청을 보내려면
componentDidMount
메서드 내부에 해당 로직을 작성하면 됩니다.
반면, 함수형 컴포넌트에서는 생명주기 메서드를 직접적으로 사용할 수 없지만, React 훅인
useEffect
를 사용하여 비슷한 효과를 낼 수 있습니다. 예를 들어,useEffect
에 빈 배열을 두 번째 인자로 전달하면componentDidMount
와 같은 효과를 얻을 수 있습니다.
함수형 컴포넌트에서 상태와 생명주기 기능을 사용할 수 있도록 도와주는 기능입니다. 가장 자주 사용되는 훅은
useState
와useEffect
입니다.
함수형 컴포넌트는
this
의 개념을 갖고 있지 않습니다. 대신useState
로 컴포넌트의 상태를 관리할 수 있게 해줍니다. 클래스형 컴포넌트에서 특정 클래스의 내부 인스턴스를 접근하기위해 쓰이는this
키워드 안에 내장된this.state
와this.setState
를 사용하는 것과 같습니다.
'useEffect'는 클래스형 컴포넌트의 생명주기 메서드('componentDidMount', 'componentDidUpdate', 'componentWillUnmount')와 유사한 기능을 제공합니다. 렌더링 이후에 어떤 작업을 수행해야 할 때 사용하며, 의존성 배열을 이용하여 특정 상태 변경시에만 실행되게 조절할 수 있습니다.
//클래스형 컴포넌트 작성을 통해 상태주기를 구현
componentDidMount() {
console.log('Component did mount');
}
componentDidUpdate() {
console.log('Component did update');
}
componentWillUnmount() {
console.log('Component will unmount');
}
//useEffect를 사용하여 상태주기를 구현
useEffect(() => {
console.log('Component did mount or did update');
return () => {
console.log('Component will unmount');
};
});
React 팀은 이전에 클래스형 컴포넌트를 사용하여 상태와 생명주기 메서드를 관리하도록 가이드하였습니다. 그러나 클래스형 컴포넌트는 여러 가지 단점이 있었습니다. 가장 중요한 것은
this
키워드에 대한 혼란이었습니다. JavaScript의this
는 다른 언어와 달리 동작하고, 특히 초보 개발자들에게 혼란을 주었습니다. 또한, 컴포넌트 로직을 재사용하기 어렵다는 문제도 있었습니다.
이런 문제를 해결하기 위해 React 팀은 함수형 컴포넌트와 Hooks를 도입하였습니다. 함수형 컴포넌트는
this
를 사용하지 않기 때문에 더 간결하고 이해하기 쉽습니다. Hooks를 사용하면 상태와 생명주기 메서드를 함수형 컴포넌트에서도 사용할 수 있습니다. 또한, Hooks는 커스텀 훅을 통해 로직을 쉽게 재사용할 수 있게 합니다.
함수형 컴포넌트와 Hooks의 사용은 몇 가지 주요 이점을 제공합니다. 첫째, 코드의 가독성이 향상됩니다. 함수형 컴포넌트는 클래스형 컴포넌트보다 간결하며, 로직이 명확하게 표현되므로 코드를 읽는 데 더 쉽습니다. 둘째, 컴포넌트 로직의 재사용이 더 쉬워집니다. 커스텀 훅을 만들어 다양한 컴포넌트에서 로직을 재사용할 수 있습니다. 셋째, 클래스의
this
에 대한 혼란이 사라집니다.