
리액트 컴포넌트는 크게 함수 컴포넌트와 클래스 컴포넌트로 나뉩니다.
이렇게 초기 버전에서는 클래스 컴포넌트를 사용하였습니다.
하지만 클래스 컴포넌트가 사용하기 불편하다는 의견이 많이 나왔고
이후에는 함수 컴포넌트를 개선해서 주로 사용하게 되었습니다.
함수 컴포넌트를 개선하는 과정에서 개발된 것이 바로 훅이라는 것인데 이것에 대해서는 7강에서 배울 예정입니다.
현재 리액트 개발에서는 거의 훅을 사용한다고 생각하시면 되는데 그렇다고 클래스 컴포넌트에 대해서 공부하지 않고 지나가는 것은 추천하지 않습니다.
왜냐하면 리액트의 기초를 탄탄하게 다지려면 클래스 컴포넌트와 6장에서 나올 컴포넌트의 라이프 사이클에 대해서 잘 이해하고 있는 것이 좋기 때문입니다.
먼저 함수 컴포넌트에 대해서 간단하게 살펴보겠습니다.
앞에서 props에 대해서 설명할 때 모든 리액트 컴포넌트는 pure한 함수 같은 역할을 해야 한다고 했습니다. 결국 리액트 컴포넌트를 일종의 함수라고 생각한다는 뜻입니다.
간단한 함수 컴포넌트 예제를 한번 보겠습니다.
function Welcome(props) {
return <h1>안녕, {props.name}</h1>;
}
이 코드에는 Welcome 이라는 이름을 가진 함수가 하나 나옵니다. 이 함수의 경우 하나의 props 객체를 받아서 인삿말이 담긴 리액트 엘리먼트를 리턴하기 때문에 리액트 컴포넌트라고 할 수 있습니다.
그리고 이렇게 생긴 것을 우리는 '함수 컴포넌트'라고 부릅니다.
코드가 굉장히 간단하죠? 함수 컴포넌트는 이처럼 간단한 코드를 장점으로 가진다고 할 수 있습니다.
클래스 컴포넌트는 자바스크립트 es6의 클래스라는 것을 이용해 만들어진 형태의 컴포넌트입니다.
클래스 컴포넌트의 경우에는 함수 컴포넌트에 비해서 몇 가지 추가적인 기능을 갖고 있습니다.
이 부분에 대해서는 뒤에서 다루도록 하겠습니다.
클래스 컴포넌트 예제 코드를 한번 보겠습니다.
class Welcome extends React.Component {
render() {
return <h1>안녕, {this.props.name}</h1>;
}
}
이 코드는 우리가 위에서 살펴본 함수 컴포넌트 Welcome과 동일한 역할을 하는 컴포넌트를 클래스 형태로 만든 것입니다.
함수 컴포넌트와의 가장 큰 차이점은
리액트의 모든 클래스 컴포넌트는 React.Component를 상속받아서 만든다는 것입니다.
상속이라는 것은 객체지향 프로그래밍에서 나오는 개념인데,
한 클래스의 변수들과 함수들을 상속받아서 새로운 자식 클래스를 만드는 방법입니다.
여기에서는 React.Component라는 클래스를 상속받아서 Welcome 이라는 클래스를 만들었고,
이는 React.Component를 상속받았기 때문에 결과적으로 리액트 컴포넌트가 되는 것입니다.
지금까지 리액트 컴포넌트의 종류에 대해 알아봤습니다. 그렇다면 컴포넌트의 이름은 어떻게 지어야 할까요? 우리가 컴포넌트의 이름을 지을 때 한 가지 유의해야 할 중요한 점이 있습니다.
Component의 이름은 항상 대문자로 시작해야 한다!
왜냐하면, 리액트는 소문자로 시작하는 컴포넌트를 DOM 태그으로 인식하기 때문입니다.
예를 들어 div나 span과 같이 사용하는 것은 '내장 컴포넌트'라는 것을 뜻하며
div나 span과 같은 '문자열' 형태로 react create element에 전달됩니다.
하지만 대문자로 시작하는 Foo 와 같이 대문자로 시작하는 경우에는
react create element 'Foo' 형태로 컴파일되며 자바스크립트 파일 내에서 사용자가 정의했거나 임포트한 '컴포넌트'를 가리킵니다. 그렇기 때문에 컴포넌트의 이름은 항상 대문자로 시작해야 합니다.
HTML div 태그로 인식
const element = <div />;
Welcome이라는 리액트 Component로 인식
const element = <Welcome name="인제" />
만약 컴포넌트의 이름을 꼭 소문자로 사용하고 싶다면 먼저 대문자로 시작하는 변수에 할당한 뒤, 이 변수를 사용하면 됩니다. 하지만 웬만하면 대문자로 사용하는 것을 권장합니다.
컴포넌트를 다 만든 이후에 실제로 렌더링 하려면 어떻게 해야 할까요? 앞에서 배운 것처럼 컴포넌트는 붕어빵 틀의 역할을 합니다. 그렇기 때문에 실제로 컴포넌트가 화면에 렌더링되는 것은 아닙니다. 컴포넌트라는 붕어빵 틀을 통해 찍어줘서 나온 엘리먼트라는 붕어빵이 실제로 화면에 보이게 되는 것이죠.
그렇다면 렌더링을 위해서는 가장 먼저 컴포넌트로부터 엘리먼트를 만들어야 되겠죠.
const element = <div />;
const element = <Welcome name="인제" />
이 코드는 앞에서 나왔던 코드와 동일한 코드인데 설명 부분이 바뀐 것입니다.
이 두 줄의 코드는 모두 리액트 엘리먼트를 만들어내게 됩니다. 그러면 우리는 이제 이 엘리먼트를 렌더링하면 되는 것이죠. 실제 렌더링하는 코드를 한번 보도록 하겠습니다.
function Welcome(props) {
return <h1>안녕, {props.name}</h1>;
}
const element = <Welcome name="인제" />;
ReactDOM.render(
element,
document.getElementById('root')
);
위 코드에서는 먼저 Welcome이라는 함수 컴포넌트를 선언하고 있습니다.
그리고 Welcome name="인제"라는 값을 가진 엘리먼트를 파라미터로 해서 ReactDOM.render 함수를 호출합니다.
이렇게 하면 리액트는 Welcome() 컴포넌트의 {name:"인제"}라는 props를 넣어서 호출하고 그 결과로 리액트 엘리먼트가 생성됩니다.
이렇게 생성된 엘리먼트는 최종적으로 ReactDOM을 통해 실제 DOM에 효과적으로 업데이트되고 우리가 브라우저를 통해서 볼 수 있게 됩니다.
컴포넌트와 Props (1)
Component컴포넌트 : 붕어빵틀 (element엘리먼트 : 붕어빵 )
- 함수 컴포넌트 vs 클래스 컴포넌트..?
리액트의 모든 '클래스' 컴포넌트는 'React.Component'를 상속받아서 만든다.
- 컴포넌트의 이름은..?
모두 대문자로 시작해야 한다.
- 컴포넌트 렌더링 방법..?
1) 컴포넌트 선언.
2) ReactDOM.render() 함수로 컴포넌트를 호출하면 엘리먼트가 생성되고 출력(=렌더링)됨.