본문 바로가기
SPA/React

React Props 그리고 vue에는 없는 신기한 함수

by memeseo 2022. 11. 1.

프로퍼티 (Properties)란?

 

  • 상위 컴포넌트에서 하위 컴포넌트에게 값을 전달할 때 사용.
  • 프로퍼티는 단방향이라는 특징이 있음.
  • 읽기 전용 데이터 이기 때문에 수정이 불가함. **

 


 

사용 방법

 

! 버튼 함수 컴포넌트를 만들어서 재활용해보자.

 

function Btn(props){
    return(
        <button>{props.btnName}</button>
    )
}

function App(){
	return (
    	<div>
        	<Btn btnName="Save Changes"/>
            <Btn btnName="Continue"/>
        </div>
    )
}

 

Btn 함수 컴포넌트에 btnName이라는 인자를 전달하여 버튼 이름을 변경하는 코드이다.

이때, Btn 함수 컴포넌트에 전달하는 인자가 몇 개이던, 받을 땐 매개 변수 하나로 받는다.

 

예시.

 

function Btn(props){
    return(
        <button>{props.btnName} : {props.newMessage}</button>
    )
}

function App(){
	return (
    	<div>
        	<Btn btnName="Save Changes" newMessage="안녕하세요"/>
            <Btn btnName="Continue" newMessage="지금은 밤 10시"/>
        </div>
    )
}

 

속성 이름을 바로 사용하고 싶을 땐? 오브젝트에서 바로 꺼내서 쓰면 된다.

 

function Btn({btnName, newMessage}){
    return(
        <button>{btnName} : {newMessage}</button>
    )
}

function App(){
	return (
    	<div>
        	<Btn btnName="Save Changes" newMessage="안녕하세요"/>
            <Btn btnName="Continue" newMessage="지금은 밤 10시"/>
        </div>
    )
}

 

* 컴포넌트에 보내는 인자는 boolean, string, function, eventListener .. 등등 뭐든 가능하다.

* React는 소문자로 시작하는 컴포넌트를 DOM태그로 처리하기 때문에 컴포넌트의 이름은 항상 대문자로 시작해야 한다. 자세한 내용은 여기 클릭

 


vue랑 달라 강의 보면서 신기했던 기능 두 가지.

 

1. memo
2. propTypes

 

1. memo

: 컴포넌트의 props가 바뀌지 않았을 때 리렌더링을 방지해주어 컴포넌트의 선능 최적화를 보장해주는 함수.

 

강의 듣다 처음 접했는데 이거 엄청 좋은 기능이잖아 .. ! (신세계)

리렌더링이 필요한 상황일때만 리렌더링을 한다니 똑똑하다 .. 똑똑해..

 

! 사용 방법

 

function Btn(props){
    return(
        <button onClick={props.changValue}>{props.btnName}</button>
    )
}

function App(){
	const [value, setValue] = React.useState("Save Changes");
    const changValue = () => setValue("Revert Changes");
    
	return (
    	<div>
        	<Btn btnName="Save Changes" changValue={changValue}/>
            <Btn btnName="Continue"/>
        </div>
    )
}

 

부모 컴포넌트에서 상태 변경을 겪으면 자식 컴포넌트가 새로 그려짐.

여기서 props가 변경된 자식 컴포넌트만 리렌더링이 되도록 하려면?

 



function Btn(props){
    return(
        <button onClick={props.changValue}>{props.btnName}</button>
    )
}

const MemorizedBtn = React.memo(Btn);

function App(){
	const [value, setValue] = React.useState("Save Changes");
    const changValue = () => setValue("Revert Changes");
    
	return (
    	<div>
        	<MemorizedBtn btnName="Save Changes" changValue={changValue}/>
            <MemorizedBtn btnName="Continue"/>
        </div>
    )
}

 

간 - 단

 

단, 무분별한 사용은 불필요한 props만 비교하는 것이 컴포넌트의 성능을 실제로 개선할 수 있는 상황에서만 해당 함수를 사용해야 한다고 한다. 

 

 

2. PropTypes

: 부모로부터 전달받은 prop의 데이터 타입을 검사하는 Extensions.

 

회사 프로젝트는 vue + vanila.js를 사용해서 개발하고 있는데, 규모가 커질 수록 해당 기능이 필요하다고 느껴서 typeScript로 전환할까 고민했었다. 근데 react에 type과 필수 요소인지 체크해주는 기능이 있다니 .. !  선택지가 하나 더 늘었다.

 

! 사용 방법

 

function Btn({text, fontSize = 16}){
    return(
        <button style={{fontSize : fontSize }}>{text}</button>
    );
}

Btn.propTypes = {
	text : PropTypes.string.isRequired,
    fontSize : PropTypes.number
};

function App(){
	const [value, setValue] = React.useState("Save Changes");
    const changValue = () => setValue("Revert Changes");
    
	return (
    	<div>
        	<Btn text="Save Changes" fontSize={18}/>
            <Btn text="Continue" fontSize={7}/>
        </div>
    )
}

 

사용 방법도 간단하다. 타입 검사를 해준다는 것도 좋지만, 코드를 뜯어보지 않아도 정보를 한눈에 확인할 수 있다는 점도 좋은 장점같다.

 

*propTypes에서 기본적으로 제공하는 타입들

 

import PropTypes from 'prop-types';

MyComponent.propTypes = {
  // prop가 특정 JS 형식임을 선언할 수 있습니다.
  // 이것들은 기본적으로 모두 선택 사항입니다.
  optionalArray: PropTypes.array,
  optionalBool: PropTypes.bool,
  optionalFunc: PropTypes.func,
  optionalNumber: PropTypes.number,
  optionalObject: PropTypes.object,
  optionalString: PropTypes.string,
  optionalSymbol: PropTypes.symbol,

  // 랜더링 될 수 있는 것들은 다음과 같습니다.
  // 숫자(numbers), 문자(strings), 엘리먼트(elements), 또는 이러한 타입들(types)을 포함하고 있는 배열(array) (혹은 배열의 fragment)
  optionalNode: PropTypes.node,

  // React 엘리먼트.
  optionalElement: PropTypes.element,

  // React 엘리먼트 타입 (ie. MyComponent)
  optionalElementType: PropTypes.elementType,

  // prop가 클래스의 인스턴스임을 선언할 수 있습니다.
  // 이 경우 JavaScript의 instanceof 연산자를 사용합니다.
  optionalMessage: PropTypes.instanceOf(Message),

  // 열거형(enum)으로 처리하여 prop가 특정 값들로 제한되도록 할 수 있습니다.
  optionalEnum: PropTypes.oneOf(['News', 'Photos']),

  // 여러 종류중 하나의 종류가 될 수 있는 객체
  optionalUnion: PropTypes.oneOfType([
    PropTypes.string,
    PropTypes.number,
    PropTypes.instanceOf(Message)
  ]),

  // 특정 타입의 행렬
  optionalArrayOf: PropTypes.arrayOf(PropTypes.number),

  // 특정 타입의 프로퍼티 값들을 갖는 객체
  optionalObjectOf: PropTypes.objectOf(PropTypes.number),

  // 특정 형태를 갖는 객체
  optionalObjectWithShape: PropTypes.shape({
    color: PropTypes.string,
    fontSize: PropTypes.number
  }),

  // 추가 프로퍼티에 대한 경고가 있는 객체
  optionalObjectWithStrictShape: PropTypes.exact({
    name: PropTypes.string,
    quantity: PropTypes.number
  }),

  // 위에 있는 것 모두 `isRequired`와 연결하여 prop가 제공되지 않았을 때
  // 경고가 보이도록 할 수 있습니다.
  requiredFunc: PropTypes.func.isRequired,

  // 모든 데이터 타입이 가능한 필수값
  requiredAny: PropTypes.any.isRequired,

  // 사용자 정의 유효성 검사기를 지정할 수도 있습니다.
  // 검사 실패 시에는 에러(Error) 객체를 반환해야 합니다.
  // `oneOfType`안에서는 작동하지 않으므로 `console.warn` 혹은 throw 하지 마세요.
  customProp: function(props, propName, componentName) {
    if (!/matchme/.test(props[propName])) {
      return new Error(
        'Invalid prop `' + propName + '` supplied to' +
        ' `' + componentName + '`. Validation failed.'
      );
    }
  },

  // `arrayOf` 와 `objectOf 에 사용자 정의 유효성 검사기를 적용할 수 있습니다.
  // 검사 실패 시에는 에러(Error) 객체를 반환해야 합니다.
  // 유효성 검사기는 배열(array) 혹은 객체의 각 키(key)에 대하여 호출될 것입니다.
  // 유효성 검사기의 첫 두 개의 변수는 배열 혹은 객체 자신과 현재 아이템의 키입니다.

  customArrayProp: PropTypes.arrayOf(function(propValue, key, componentName, location, propFullName) {
    if (!/matchme/.test(propValue[key])) {
      return new Error(
        'Invalid prop `' + propFullName + '` supplied to' +
        ' `' + componentName + '`. Validation failed.'
      );
    }
  })
};

 

커스텀 함수도 작성할 수 있다고 하니 에러 메시지를 출력하는 유효성 검사를 만들어봐도 좋을 것 같다.

 

참고. React.PropTypes는 v15.5부터 다른 패키지로 이동해서 props-types 라이브러리를 사용 권장.

'SPA > React' 카테고리의 다른 글

React Router  (0) 2022.11.21
React Effect Hook  (0) 2022.11.07
React State  (0) 2022.10.26
JSX 문법  (0) 2022.10.19
vanilla.js vs react.js  (0) 2022.10.19