React 개발에 중수? 고수가 아니라면 오픈 소스 개발자나 아른 소프트웨어 엔지니어, 동료가 만든 컴포넌트에 의존해야 하는 좀 큰 프로젝트에서 문제를 경험하게 될 것이다.
예를들면, 다른 개발자가 만든 컴포넌트를 사용할 때 속성을 제대로 전달했는지, 다른 컴포넌트에서도 공통적으로 사용할 약간의 기능을 기존 컴포넌트에도 적용하려면 어떻게 하는지, 등등의 '개발 확장성 문제'에 부딪친다.
React에는 확장성을 고려할 때 도움이 되는 기능과 패턴이 있다.
이 중, '속성 타입'은 안정적인 타입 검사를 제공하고 컴포넌트의 온전성을 보장한다.
'속성 타입'을 이용하면 좀 더 개발자 친화적인 코드를 만들 수 있다.
컴포넌트의 기본 속성
먼저 예시를 하나 들면,
행의 수(rows), 언어(locale), 현재 날짜(current date)를 필수 속성으로 갖는 Datepicker 컴포넌트가 있다고 생각해보자.
< Datepicker currentDate={Date()} locale="US" rows={4} />
위와 같이 작성할 수 있을 것이다.
하지만 만약에 동료가 이 컴포넌트를 사용하면서 필수 속성인 locale을 누락했다면? 행의 수를 적으면서 숫자 4가 아닌 문자열 4를 입력했다면? 분명 오류가 날 것이다.
자바스크립트는 느슨한 타입 언어여서 이런 경우가 어렵지 않게 발생한다.
하지만 React는 속성의 기본값을 설정할 수 있는 기능으로 defaultProps를 정적 클래스 속성으로 추가할 수 있게 한다.
defaultProps를 설정하면, 컴포넌트 속성이 누락되었을 때 기본값을 렌더링 할 수 있는 강점이 있다. defalutProps를 정의해서 컴포넌트 클래스에 기본 속성을 설정한다.
위의 코드를 참고해서 예시를 보여주면 아래와 같다.
class Datepicker extends React.Component{
~~~
}
Datepicker.defaultProps = {
currentDate : Date(),
rows : 3,
locale : 'US'
}
※ constructor()에서 인스턴스 속성으로 추가하면 정상 작동하지 않는다!
조금 더 자세히 알기 설명하기 위해 보다 나은 예시를 들면 아래와 같다.
class Button extends React.Component{
renter(){
return < button className="btn">{this.props.buttonLabel}</button>
}
}
Button.defaultProps = {buttonLabel : 'Submit'}
class Content extends React.Component{
render(){
return(
<div>
<Button buttonLabel = "Success"/>
<Button />
<Button />
<Button />
</div>
)
}
}
위와 같은 Button 컴포넌트가 있었을 때, 일반적으로 버튼에 라벨이 있긴 하지만, 라벨을 사용자정의할 수 있으면 더 좋다. 또한, 사용자 정의 값이 누락된 경우에는 기본값을 보여주길 원한다.
버튼의 라벨은 buttonLabel 속성으로 render()의 return 문에서 사용한다. 부모가 버튼에 별도로 라벨을 지정하지 않아도 Submit이라는 텍스트를 보여주길 원한다.
그렇다면 위와 같이 buttonLabel의 기본 값을 포함한 객체인 정적 클래스 속성 defaultProps를 구현하면 기본 라벨을 보여줄 수 있다.
위 코드를 렌더링 하면, 첫 번째 버튼의 라벨에는 Success가 적혀있고, 나머지 버튼의 라벨에는 Submit이 적혀있다.
컴포넌트에 기본 속성 값을 설정하는 것은 좋은 방법이다. 오류에 더 잘 대응할 수도 있다. 즉, 아무런 값을 전달하지 않았을 때도 최소한의 형태를 유지하는, 좀 더 똑똑한 컴포넌트를 만들 수 있게 한다.
다른 관점으로는, 기본값을 설정해서 같은 값을 반복해서 다시 설정하는 것을 피할 수도 있다.