컴포넌트의 기능은 단순한 템플릿 이상이다. 데이터가 주어졌을 때 이에 맞추어 UI를 만들어 주는 것은 물론이고, 라이프사이클 API를 이용하여 컴포넌트가 화면에서 나타날 때, 사라질 때, 변화가 일어날 때 주어진 작업들을 처리할 수 있으며, 임의 메서드를 만들어 특별한 기능을 붙여줄 수 있다.
컴포넌트를 선언하는 방식은 두 가지이다. 하나는 함수형 컴포넌트이고, 또 다른 하나는 클래스형 컴포넌트이다.
import React, { Component } from 'react';
class App extends Component {
render() {
const name = 'react';
return <div className="react">{name}</div>;
}
}
export default App;
클래스형 컴포넌트와 함수형 컴포넌트의 차이점은 클래스형 컴포넌트의 경우 state 기능 및 라이프사이클 기능을 사용할 수 있다는 것과 임의 메서드를 정의할 수 있다는 것이다.
클래스형 컴포넌트에서는 render 함수가 꼭 있어야 하고, 그 안에서 보여 주어야 할 JSX를 반환해야 한다.
그렇다면 컴포넌트를 선언할 수 있는 두 가지 방법 중 어느 상황에 함수형 컴포넌트를 사용해야 할까?
함수형 컴포넌트의 장점을 나열해 보면 다음과 같다. 우선 클래스형 컴포넌트보다 선언하기가 훨씬 편하고, 메모리 자원도 클래스형 컴포넌트보다 덜 사용한다.
함수형 컴포넌트의 주요 단점은 state와 라이프사이클 API의 사용이 불가능하다는 점이었지만, 이 단점은 리액트 v16.8 업데이트 이후 Hooks라는 기능이 도입되면서 해결되었다. 리액트 공식 매뉴얼에서는 컴포넌트를 새로 작성할 때 함수형 컴포넌트와 Hooks를 사용하도록 권장하고 있다. 하지만 그렇다고 해서 클래스형 컴포넌트가 사라지는 것은 아니므로 클래스형 컴포넌트의 기능은 꼭 알아두어야 한다.
컴포넌트의 생성 과정은 다음과 같다.
위 작성한 코드에서 맨 아래 코드를 확인해 보자.
export default MyComponent;
이 코드는 다른 파일에서 이 파일을 import할 때, 위에서 선언한 MyComponent 클래스를 불러오도록 설정한다.
이번에는 App 컴포넌트에서 MyComponent 컴포넌트를 불러와서 사용해 보자.
props는 properties를 줄인 표현으로 컴포넌트 속성을 설정할 때 사용하는 요소이다. props 값은 해당 컴포넌트를 불러와 사용하는 부모 컴포넌트에서 설정할 수 있다.
props 값은 컴포넌트 함수의 파라미터로 받아 와서 사용할 수 있다. props를 렌더링할 때는 JSX 내부에서 { } 기호로 감싸주면 된다.
App 컴포넌트에서 MyComponent의 props 값을 지정해 보자.
위 App 컴포넌트에서 MyComponent의 props 값을 지정하지 않는다면 브라우저에는 '안녕하세요, 제 이름은 입니다.'라는 내용만 보일 것이다. 이렇게 props 값을 따로 지정하지 않았을 때 보여줄 기본값을 설정하려면 defaultProps를 사용하면 된다.
리액트 컴포넌트를 사용할 때 children props를 사용하여 컴포넌트 태그 사이의 내용을 보여줄 수 있다.
현재 MyComponent에서 props 값을 조회할 때마다 props.name, props.children과 같이 props. 이라는 키워드를 앞에 붙여 주고 있다. ES6의 비구조화 할당 문법을 사용하여 내부 값을 바로 추출하는 방법을 알아보자.
이렇게 객체에서 값을 추출하는 문법을 비구조화 할당(destructuring assignment)이라고 부른다. 이 문법은 구조 분해 문법이라고도 불리며, 함수의 파라미터 부분에서도 사용할 수 있다. 만약 함수의 파라미터가 객체라면 그 값을 비구조화해서 사용하는 것이다.
컴포넌트의 필수 props를 지정하거나 props의 타입을 지정할 때는 propTypes를 사용한다. 컴포넌트의 propTypes를 지정하는 방법은 defaultProps를 설정하는 것과 비슷하다. 우선 propTypes를 사용하려면 코드 상단에 import 구문을 사용하여 불러와야 한다.
이렇게 설정해 주면 name 값은 무조건 문자열(string) 형태로 전달해야 된다는 것을 의미한다. 만약 컴포넌트에 설정한 props가 propTypes에서 지정한 형태와 일치하지 않는다면 브라우저 개발자 도구의 Console 탭에 다음과 같은 결과가 나타난다.
propTypes를 지정하지 않았을 때 경고 메시지를 띄워주려면, propTypes를 지정할 때 뒤에 isRequired를 붙여 주면 된다.
클래스형 컴포넌트에서 props를 사용할 때는 render 함수에서 this.props를 조회하면 된다.
defaultProps와 propTypes는 꼭 사용해야 할까?
이 두 가지 설정은 컴포넌트의 필수 사항이 아니므로 꼭 사용할 필요는 없다. 하지만 큰 규모의 프로젝트를 진행할 경우, 특히 다른 개발자들과 협업할 경우에는 해당 컴포넌트에 어떤 props가 필요한지 쉽게 알 수 있어 개발 능률이 좋아질 수 있다.