# PropTypes 작동 원리

### PropTypes 작동 원리

처음 `PropTypes`을 공부 했을 때, 속성의 타입을 검사해주는 프로그램인 줄 알았다. `import` 해서 불러올 수 있다는 것은  함수가 있고, 네임스페이스 객체로 볼 수 있다는 것인데 이해가 부족했던 것 같다.&#x20;

PropTypes 구문을 암기 하는 것이 아닌 한 번 원리를 이해하며 직접 속성의 타입을 검사해주는 유틸리티 함수를 만들어보자!&#x20;

먼저 간단히 속성을 전달 받는 컴포넌트를 만들어보자&#x20;

* App 컴포넌트에 props.x는 number를 전달 받고, props.y boolean 값을 전달 받는다.

```javascript
import { StrictMode } from "react";
import ReactDOM from "react-dom";

function App(props) {
  const { x, y } = props;
  return (
    <div className="App">
      <h1>PropTypes 작동 원리 {x}</h1>
      <h2>{y ? "PropTypes는 네임스페이스 객체" : null}</h2>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(
  <StrictMode>
    <App x="10" y="true" />
  </StrictMode>,
  rootElement
);
```

자 이제 컴포넌드의 props 속성을 확인 하기 위해 propTypes를 선언해서 확인한다. 이 때, x(...argt)로 나머지 연산자를 사용해서 해당 속성이 받는 객체를 전부 확인해보자.&#x20;

```javascript
App.propTypes = {
  x(...argt) {
    console.log(argt);
  }
};
```

아래 이미지는 `console.log(argt)`의 출력 결과이다.&#x20;

![](https://831271375-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MSRg9KgNRIGErVFy_6g%2F-MT06y7EASJRlJhecJSy%2F-MT09AyUMDVUWyAObJZf%2Fimage.png?alt=media\&token=ac398895-efab-4f34-a8e0-e461132cf1d2)

![](https://831271375-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MSRg9KgNRIGErVFy_6g%2F-MT06y7EASJRlJhecJSy%2F-MT09GgoZUeQovPf7Z3s%2Fimage.png?alt=media\&token=b68c0560-14ba-4ee6-b8cc-cbcbbc5dab08)

* 0 → props : Object
* 1 → propName: "x"
* 2 → componentName: "App" &#x20;

각 0-2번은 `props`, `propName`, `componentName` 속성의 데이터이다. 이를 통해 알 수 있는 것은 속성에 접근하는 방법을 유추할 수 있다.&#x20;

### 유틸리티 함수  <a href="#utils-function" id="utils-function"></a>

위의 속성의 데이터 타입 데이터를 통해서 아래와 같이 속성의 데이터를 확인하는 유틸리티 함수를 만들 수 있다.&#x20;

```javascript
App.propTypes = {
  x(props, propName, componentName) {
    // App 컴포넌트에 전달된 속성 'x'는 'number' 타입이어야 합니다.
    const value = props[propName]; 
    const valueType = typeof value;
    if (valueType !== "number") {
      throw new Error(
        `${componentName} 컴포넌트에 전달된 속성 '${propName}'는 'number' 타입이어야 하지만, 전달 속성 타입은 '${valueType}' 입니다.`
      );
    }
  }
};
```

#### 네임 스페이스 만들기  <a href="#name-space" id="name-space"></a>

위의 유틸리티 함수에 네임 스페이스를 사용할 수 있다.&#x20;

```javascript
const PropTypes = {
  number(props, propName, componentName) {
    // App 컴포넌트에 전달된 속성 'x'는 'number' 타입이어야 합니다.
    const value = props[propName];
    console.log(value);
    const valueType = typeof value;
    console.log(valueType);
    if (valueType !== "number") {
      throw new Error(
        `${componentName} 컴포넌트에 전달된 속성 '${propName}'는 'number' 타입이어야 하지만, 전달 속성 타입은 '${valueType}' 입니다.`
      );
    }
  },
  bool(props, propName, componentName) {
    const value = props[propName];
    const valueType = typeof value;
    if (valueType !== "boolean") {
      throw new Error(
        `${componentName} 컴포넌트에 전달된 속성 '${propName}'는 'boolean' 타입이어야 하지만, 전달 속성 타입은 '${valueType}' 입니다.`
      );
    }
  }
};
```

위의 네임스페이스 객체는 아래와 같이 사용할 수 있다. 어디서 많이 본 느낌이 든다. 바로 앞서 공부한 Prop 검사 패키지인 PropTypes와 매우 유사하다.&#x20;

```javascript
App.propTypes = {
  x: PropTypes.number,
  y: PropTypes.bool
};
```

> 더 나아가서 생각하면 해당 PropTypes 기능을 나도 만들어서 오픈 소스로 배포할 수 있지 않을까 생각해본다.&#x20;

## 참고   <a href="#notes" id="notes"></a>

{% embed url="<https://codesandbox.io/s/reactyi-proptypes-paekiji-jagdong-weonri-forked-rghs1?fontsize=10&hidenavigation=1&theme=light&view=editor>" %}
