자바스크립트는 동적 타입 언어입니다. 타입에 관한 고민을 안하고 프로그램을 작성할 수 있고, 또 실행시킬 수도 있습니다. 따라서 배우기 쉽고, 간단한 프로그램을 작성할 때에는 생산성이 좋기도 합니다. 하지만, 큰 규모의 프로그램을 작성할 때는 오히려 생산성이 떨어집니다.
우리가 리액트를 배우려는 것은 간단한 프로그램만 작성하려는 것이 아니기 때문에, 가능하면 정적 타입 언어를 사용하는 것이 좋습니다. 이 때문에 타입 스크립트가 인기를 얻고 있습니다.
하지만 상황이 여의치 않아서 동적 타입 언어인 순수 자바스크립트를 사용해야 하는 경우도 있습니다. 이를 위해서 리액트에서는 속성값 타입을 정의할 수 있는 prop-types 패키지를 제공하고 있습니다. prop-types는 타입 오류를 사전에 검사할 수 있기 때문에 타입스크립트 만큼은 아니더라도 도움이 됩니다. 또한, 타입 정의 자체가 훌륭한 문서가 된다는 장점이 있습니다.
리액트 문서에 있는 내용을 보면, props-types 패키지는 array, bool, func, number, object, string 등의 자바스크립트 기본 타입을 지정할 수 있습니다. 그 밖에도 PropTypes.oneOf 를 사용하여 특정 값의 범위를 제한하거나, PropTypes.element 를 사용하여 리액트 요소타입도 지정할 수 있습니다.
import PropTypes from 'prop-types';
MyComponent.propTypes = {
optionalArray: PropTypes.array,
optionalBool: PropTypes.bool,
optionalFunc: PropTypes.func,
optionalNumber: PropTypes.number,
optionalString: PropTypes.string,
optionalEnum: PropTypes.oneOf(['News', 'Photos']),
};
그리고 PropTypes.array.isRequired 와 같이 뒤에 isRequired 값이 붙으면 필수값을 의미합니다.
import PropTypes from 'prop-types';
MyComponent.propTypes = {
optionalArray: PropTypes.array.isRequired,
optionalBool: PropTypes.bool.isRequired,
optionalFunc: PropTypes.func.isRequired,
optionalNumber: PropTypes.number.isRequired,
optionalString: PropTypes.string.isRequired,
optionalEnum: PropTypes.oneOf(['News', 'Photos']).isRequired,
};
prop-types 에서 함수형 타입인 PropTypes.func 는 파라미터와 반환값을 알기가 힘듭니다. 따라서 아래와 같이 파라미터와 반환값을 주석으로 표기해주면 좋습니다.
import PropTypes from 'prop-types';
MyComponent.propTypes = {
optionalFunc: PropTypes.func, // {param1: string, param2: number} => void
};
좀 더 자세하게 알고 싶다면 아래의 링크를 참조하시면 됩니다.
reactjs.org/docs/typechecking-with-proptypes.html
위에서 언급했던 내용처럼 prop-types는 기본형 타입을 제외하고도 여러가지 타입 및 기능을 제공하고 있습니다. 이번에는 그 타입 및 기능에 대해서 알아보도록 하겠습니다.
PropTypes.element
리액트 요소를 의미하는 타입입니다. 따라서 div, a, p 와 같이 HTML 태그나 <SomeComponent /> 와 같이 리액트 요소가 전달 되는 경우에만 참이 되고, 123 같이 리액트 요소가 아닌 값이 들어간다면 거짓이 됩니다.
import PropTypes from 'prop-types';
MyComponent.propTypes = {
// 리액트 요소
// <div>Hello</div> => 참
// <SomeComponent /> => 참
// 123 => 거짓
prop1: PropTypes.element,
};
ProtoTypes.node
이 타입은 컴포넌트 함수가 반환할 수 있는 모든 것을 말합니다. 기본형 타입, 리액트 컴포넌트 타입 모두를 말합니다.
import PropTypes from 'prop-types';
MyComponent.propTypes = {
// 컴포넌트 함수가 반환할 수 있는 모든 것
// number, string, array, element, ... => 참
// <SomeComponent /> => 참
// 123 => 참
prop1: PropTypes.node,
};
ProtoTypes.instanceOf
이 타입은 특정 클래스의 객체인지를 검사해 줍니다. 예를들어 prop1 변수가 Message 클래스의 인스턴스로 생성된 객체라면 instanceOf(Message) 라고 타입을 정의 했을 때에 참을 반환합니다.
import PropTypes from 'prop-types';
MyComponent.propTypes = {
// Message 클래스로 생성된 모든 객체
// new Message() => 참
// new Car() => 거짓
prop1: PropTypes.instanceOf(Message),
};
ProtoTypes.oneOf
이 타입은 특정 타입을 지정하는 것 보다는 지정된 값 중 하나가 들어오도록 선택하는 느낌이 강합니다. 나열된 값들중 하나가 들어오지 않는다면 거짓을 반환합니다.
import PropTypes from 'prop-types';
MyComponent.propTypes = {
// 배열에 포함된 값 중에서 하나를 만족
// 'jone' => 참
// 'messy' => 거짓
prop1: PropTypes.oneOf(['jone', 'mike']),
};
ProtoTypes.oneOfType
이 타입은 나열된 값들 중 하나가 아니라 나열된 타입중 하나를 만족하는 경우입니다. 저는 개인적으로 이것을 사용하지 않습니다. 기본형 타입을 2개 이상으로 제한한다는 것은 타입을 지정해 주는 의미가 없다고 생각을 하기 때문입니다.
import PropTypes from 'prop-types';
MyComponent.propTypes = {
// 배열에 포함된 타입 중에서 하나를 만족
// 123 => 참
// 'messy' => 참
prop1: PropTypes.oneOfType([PropTypes.number , PropTypes.string]),
};
ProtoTypes.arrayOf
이 타입은 배열에 들어갈 요소의 타입을 지정할 수 있습니다. 예를들어 매개변수로 PropTypes.number 를 넣어주면 이 배열에 숫자가 아니라 다른 타입이 들어가면 거짓을 반환합니다.
import PropTypes from 'prop-types';
MyComponent.propTypes = {
// 특정 타입만 포함하는 배열
// [1, 5, 7] => 참
// [1, 2, 3 'a'] => 거짓
prop1: PropTypes.arrayOf(PropTypes.number),
};
ProtoTypes.shape
이 타입은 객체의 속성값 타입을 정의할 수 있습니다. 예를들면 객체에 name 속성과 description 속성이 있을 때, 그 속성의 타입을 아래와 같이 문자열로 지정할 수 있습니다.
import PropTypes from 'prop-types';
MyComponent.propTypes = {
// 객체의 속성값 타입을 정의
// {name: 'horong', description: 'My name is horong'} => 참
// {name: 'horong', description: 123} => 거짓
prop1: PropTypes.shape({
name: PropTypes.string,
description: PropTypes.string
}),
};
타입을 함수로 정의하여 보다 세부적인 조건을 부여할 수 있습니다. 예를들어보겠습니다. age 라는 나이를 입력하는 변수가 있습니다. 이 변수가 10보다 작거나 20보다 큰 경우에 에러로그가 찍히도록 하려고 합니다. 이러한 경우에는 아래와 같은 코드로 작성할 수 있습니다.
import PropTypes from 'prop-types';
MyComponent.propTypes = {
age: function(props, propName, componentName) {
const value = props[propName];
if(value < 10 || value > 20) {
return new Error(
`Invalid prop ${propName} supplied to ${componentName}.
It must be 10 <= value <= 20.`
);
}
}
};
출처 : 실전 리액트 프로그리맹 - 인프런 (추천합니다 !!)
[Frontend/React] 18. 재사용성을 고려한 컴포넌트의 분리 (0) | 2020.10.05 |
---|---|
[Frontend/React] 17. 가독성을 높이는 조건부 렌더링 방법 (0) | 2020.10.05 |
[Frontend/React] 15. 컴포넌트 파일 작성법 (0) | 2020.10.04 |
[Frontend/React] 14. 리액트 내장 훅 살펴보기 (0) | 2020.10.03 |
[Frontend/React] 13. 자식 요소에 접근하기 (0) | 2020.10.03 |