TIL - React: PropType을 이용해 props 값 불러오기

신혜린·2023년 9월 25일
0

TIL

목록 보기
11/19
post-thumbnail

Storybook 으로 StyledRadio를 만들고 있던 와중, docgenInfoprops 정보를 불러오려고 했으나 props 가 없다!? 이 문제를 어떻게 해결했는지 기록.


왜 자꾸 props를 인식 못하지?

StyledRadio.stories.js 파일에 StyledRadio의 props을 전달하여 각각의 프롭들에 대해 타입 및 값을 정의하려고 했으나, 자꾸만 프롭을 불러오지 못한다는 오류가 떴다.

// StyledRadio.stories.js
value.args = {
  value: 'value',
  Val: 'different value',
};

이런 식으로 코드를 작성하면 value 라는 프롭 자체를 인식을 못하는 것이다.

나는 분명 StyledRadio 컴포넌트에서 프롭들을 잘 보내주고 있다고 생각했는데 무엇이 문제였을까 하고 한참을 헤매기 시작했다.


prop이 불러와지고 있긴 한 건가?

우선 프롭들이 잘 불러와지고 있긴 한 걸까? 라는 의문이 먼저 들었다.

그래서 StyledRadio.__docgenInfo 를 콘솔창에 찍은 후 props 가 제대로 불러와지고 있긴 한 건지 확인해보려고 했으나 안 찍히고 있음을 알게 되었다.

-> prop 키값은 증발해버린 상태(!)

그래서 다시 StyledRadio 컴포넌트로 돌아가 prop들이 제대로 전달이 안되고 있는 건가 싶어 나의 코드를 확인해보았다.

// 수정 전 { StyledRadio }
export const StyledRadio = (props) => {
  const { Name, 
					Val, 
					Disabled, 
					Width, 
					Height, 
					isDark = false, 
					value, 
					modelValue, 
					onChange } = props;
...
}
  • StyledRadio 라는 이름으로 함수형 컴포넌트를 선언하고, props 를 매개변수로 받는다.
  • 구조 분해 할당을 사용하여 props 객체에서 필요한 프로퍼티들을 추출한다.

…를 의도하고 작성한 코드이긴 하나, 오류가 나니 값을 정의해주지 않아서 그런 건가 싶어 다음과 같이 수정해보았다.

  • 왜냐하면 StyledButton 컴포넌트에서는 프롭 전달할 때 모두 값을 정의했음.
    // { StyledButton }
    export const StyledButton = ({
      width = 'auto',
      size = 'medium',
      color = 'primary',
      outlined = false,
      disabled = false,
      loading = false,
      Type = 'button',
      to = null,
      HeightUnit = [24, 28, 36, 44, 52],
      PaddingUnit = [8, 8, 10, 14, 14],
      FontSizeUnit = [12, 13, 14, 16, 16],
      FontWeightUnit = [600, 600, 700, 700, 700],
      BorderRadiusUnit = [4, 4, 6, 6, 6],
      children,
    }) => {
    ...
    }
// 1차 수정 후 { StyledRadio }
export const StyledRadio = (props) => {
  const {
    Name = null,
    Val = null,
    Disabled = false,
    Width = 26,
    Height = 26,
    isDark = false,
    value = null,
    modelValue = null,
    onChange = () => {},
  } = props;
...
}
  • 왜 이렇게 null 값이 많은 건지? → 이렇게 수정한 이유는 기존의 🔆vue에서 react로 변환하는 과정과 연관이 있다.

🔆Vue에서 React로 변환하는 과정 중

StyledButton의 경우에는 Vue 와 React 내에 다음과 같이 작성되어 있었다.

// styledbutton.vue
props: {
    size: {
      type: String,
      default: 'medium',
      validator: function (value) {
        // TODO: 'x-small'
        return ['x-small', 'small', 'medium', 'large', 'x-large'].indexOf(value) > -1
      }
    },
    width: {
      type: [Number, String],
      default: 'auto' // 200, '200px', '100%', 'auto'
    },
    color: {
      type: String,
      default: 'primary',
      validator: function (value) {
        return ['primary', 'secondary', 'grey', 'yellow'].indexOf(value) > -1
      }
    },
...

// styledbutton.jsx
export const StyledButton = ({
  size = 'medium',
  width = 'auto',
  color = 'primary',
  ...
}) => {}
  • styledbutton.jsx 파일 내 코드를 보면 각각의 프롭들에 대한 값이 styledbutton.vue 파일 내 default 값으로 정의되어 있는 것을 알 수 있다.
// styledradio.vue
props: {
    value: {
      // Comes from 'v-model' value of component element (vue2)
      type: [String, Number],
    },
    modelValue: {
      // Comes from 'v-model' value of component element (vue3)
      type: [String, Number],
    },
    Name: {
      required: true,
    },
    Val: {
      required: true,
    },
    Disabled: {
      type: Boolean,
      default: false,
    },
    Width: {
      type: Number,
      default: 26,
    },
    Height: {
      type: Number,
      default: 26,
    },
  },
  • 하지만 styledradio.vue 에는 default 값이 존재하지 않는 프롭들이 많았다. → 그래서 값이 없다고 생각하고 null 값을 부여한 것.

하지만 이렇게 수정하니 의도한 대로 storybook control 바에 나타나지 않는 것이다. vue-storybook 내에는 특정 프롭의 값들이 null 이 아니라 value 라고 정의가 되어있는데 무언가 맞지 않다는 생각이 들어 다른 방법을 찾아보게 되었다.


어떻게 하면 docgenInfo 가 프롭을 인식할 수 있을까?

우선 원하는 프롭을 제대로 인식해와야 prop.arg 부분에서 오류 나는 것을 해결할 수 있다.

StyledButton에서는 프롭마다 값을 정의해줬기에 docgenInfo로도 prop값을 인식할 수 있었다.

🤔 그 값을 vue 코드 내 default 값과 통일해줬으나, StyledRadio 프롭들에는 default가 없는 게 문제…

그러다가 새롭게 배운 내용은 default 값이 없어도 type을 선언해주면 docgenInfo에서 prop 값을 읽을 수 있다는 것이다!

import PropTypes from 'prop-types'; 을 추가해주면 됨.

PropTypes와 함께 하는 타입 검사 – React

  • PropTypes 는 전달받은 데이터의 유효성을 검증하기 위해 다양한 유효성 검사기(Validator)를 보낸다. 이런 유효성 검사기 덕분에 docgenInfo를 찍어었을 때에도 prop 값이 인식된다는 의미인 것 같다.

이렇게 PropTypes 를 import 해와오니 다시 docgenInfo 를 이용해 props 키값을 불러오는 게 가능해졌다. (잃어버린 프롭 찾기 성공 🥲)

import PropTypes from 'prop-types';

StyledRadio.propTypes = {
  Name: PropTypes.string,
  Val: PropTypes.string,
  Disabled: PropTypes.bool,
  Width: PropTypes.number,
  Height: PropTypes.number,
  isDark: PropTypes.bool,
  value: PropTypes.string,
  modelValue: PropTypes.string,
  onChange: PropTypes.func,
};

💡 아직 vue에 대한 개념 정리도 잘 잡히지 않은 상태이고, 그런 vue를 react로 변환하려고 하다보니 많은 게 혼란스러운 게 사실이다.
그래서 위와 같이 vue.js 내 프롭의 디폴트 값이 정의되어 있지 않은 경우엔 갑자기 docgenInfo 가 프롭 키를 불러오지 못한다는 게 당황스럽기도 했으나 이런 식으로 해결 방법을 찾다니 ..!! 코딩의 길은 무궁무진하구나 싶다.

profile
개 발자국 🐾

0개의 댓글