안녕하세요 prop-types에 대한 포스팅입니다.
prop-types는 Reactv15.5 이전에는 React.PropTypes였습니다. 이후에 별도의 라이브러리 prop-types로 이동했습니다.
prop-types는 속성값의 타입 정보를 정의할 때 사용하는 리액트 공식패키지입니다. 속성값의 타입을 정의하면 앱이 커짐에 따라 발생하는 예기치못한 버그를 잡을 수 있습니다. prop-types를 사용하지 않을 수도 있지만, 컴포넌트 코드의 가독성과 예기치못한 버그를 막기 위해 필수로 작성하는게 좋습니다.
prop-types패키지를 이용하면 컴포넌트에 잘못된 타입이 입력할 때 콘솔에 에러메세지를 출력합니다. 리액트가 렌더링하는 과정에서 잘못된 속성값 타입을 검사해 주기 때문입니다.
prop-types를 사용할 때 생기는 또 다른 장점은 타입 정의 자체가 훌륭한 문서가 된다는 점입니다. 컴포넌트를 일일이 들여다보지 않아도 prop-types를 코드의 윗부분에 작성해두면 속성값 정보를 쉽게 파악할 수 있습니다.
prop-types는 성능상의 이유로 개발모드에서만 동작합니다.
npm i prop-types
두 가지 방법으로 작성합니다.
class MyComponent extends React.Component {
static propTypes = {
// 여기에작성
}
// ...
}
class MyComponent Extends React.Component {
// ...
}
MyComponent.propTypes = {
// 여기에작성
}
상단에 작성하는 것을 권장하는 이유는 코드의 가독성을 높혀주기 때문입니다.
상단에 작성하는 방식으로 prop-types를 만들어보겠습니다.
부모컴포넌트를 작성하고, props를 받는 자식컴포넌트에서 prop-types를 이용해 속성값의 타입을 지정해보겠습니다.
잘 못된 타입이 속성값으로 들어왔을 경우 에러가 발생합니다.
import React from 'react'
import Child from "./ChildComponent";
export default class MyComponent extends React.Component {
render () {
return (
<div>
<Child name='jack'></Child>
</div>
)
}
}
import React from 'react'
import propTypes from 'prop-types'
import Message from './Message'
export default class Child extends React.Component {
static propTypes = {
// 리액트 요소
// <div>hello</div> => 참
// <SomeComponent/> => 참
// 123 => 거짓
menu : propTypes.element,
// 렌더 함수가 리턴할 수 있는 모든 것
// number,string,array,element 또는 이러한 타입을 포함하고있는 배열
// <SomeComponent /> => 참
// 123 => 참
description:propTypes.node,
// Message클래스로 생성된 모든 객체
message : propTypes.instanceOf(Message),
// 배열에 포함된 값중에서 하나를 만족
// 'jone' => 참
// 'messy' => 거짓
name : propTypes.oneOf(['jone','mike']),
// 배열에 포함된 타입중에서 하나를 만족
// 123 => 참
// 'messy' => 참
width : propTypes.oneOfType([propTypes.number , propTypes.string]),
// 특정 타입만 포함하는 배열
ages : propTypes.arrayOf(propTypes.number),
// 객체의 속성값 타입 정의
info : propTypes.shape({
color : propTypes.string,
weight : propTypes.number
}),
// 객체에서 모든 속성값이 타입이 같은 경우
infos : propTypes.objectOf(propTypes.number)
}
render () {
return (
<div>
</div>
)
}
}
가능하면 자세하게 작성하는게 좋습니다. 당연한 이유로 propTypes.node처럼 광범위한 타입제한은 상황에 따라 쓸모가 없을 수도 있습니다.
prop-types는 타입 정의함수를 제공합니다.
커스텀 속성값 타입을 정의하는 함수를 만들어보겠습니다.
먼저 제공되는 매개변수는 뭐가 있을지 보겠습니다.
// 부모컴포넌트
export default class MyComponent extends React.Component {
render () {
return (
<div>
<Child name='jack' customProp='custom'></Child>
</div>
)
}
}
// 자식컴포넌트
export default class Child extends React.Component {
static propTypes = {
// ...
customProp : (props, ...rest) => {
console.log({...rest})
console.log(props)
}
}
}
부모컴포넌트에서 속성값을 name='jack'을, customProp='custom' 을 넘겼습니다.
▼ 콘솔에서 출력되는 매개변수확인
첫 번째 매개변수 props는 속성값들을 담은 객체리터럴을 받습니다.
두 번째 매개변수는 컴포넌트의 이름입니다.
세 번째 부터는 사실 잘 모르겠습니다 -.-
다섯 번째는 경고메세지가 나오네요
아무튼 중요한 건 사용할 수 있는 매개변수는
입니다.
전해지는 매개변수를 이용해서 현재 속성의 값을 참조할 수 있는 방법은
export default class Child extends React.Component {
static propTypes = {
// ...
customProp : (props, propsName, componentName) => {
console.log(props[propsName])
}
// ...
}
이렇게 하면 현재 타입정보를 작성하려고 하는 속성값의 value를 출력할 수 있습니다.
customProp 수정
customProp : (props, propName, componentName) => {
if(props[propName] !== 'custom') {
return new Error(`Invalid prop ${propName} suppied to ${componentName} ^^`)
}
}
custom이라는 문자열이 안넘어오면 에러를 반환하게 작성했습니다.
부모컴포넌트에서 잘못된 속성값 넘겨보기
export default class MyComponent extends React.Component {
render () {
return (
<div>
<Child customProp='hello'></Child>
</div>
)
}
}
▼ 직접 작성한 에러메세지가 출력됩니다.
직접 작성한 에러 메세지가 콘솔에 빨간글씨로 출력되는 걸 보니 뿌듯합니다.
defaultTypes는 말 그대로 기본으로 사용할 속성값입니다. 부모컴포넌트에서 속성값이 전달되지 않을 경우 사용할 값들인데, 이 defaultTypes를 객체로 작성하게되면, propTypes는 defaultTypes가 적용 된 뒤에 타입검사를 진행합니다. defaultTypes로 기본값으로 적용된 값들도 타입검사를 하기위해서 입니다.
static defaultProps = {
message : 'hi'
}
static propTypes = {
message : propTypes.instanceOf(Message),
// ...
}
defaultProps가 적용된 후, propTypes의 타입검사를 진행합니다.
message는 instanceOf(Message)로 Message컴포넌트의 인스턴스여야 하기 때문에 에러가 예상됩니다.
여기까지입니다. 마치겠습니다.
읽어주셔서 감사합니다!