📑 Nomad Coders ‘ReactJS로 영화 웹 서비스 만들기’ 강의를 듣고 정리한 내용입니다.




Props

하나의 어플리케이션에는 여러 버튼들이 있고 그 버튼들은 모두 같은 디자인을 하고있다.
UI를 통일시키는게 디자이너의 일이다.
그러면 여러 버튼 컴포넌트들을 만들고 모두 같은 스타일을 넣어줘야 하는가?
그렇지 않다.
하나의 버튼을 만들고 그 안의 텍스트 내용이나 버튼을 눌렀을 때 기능만 다르게 넣어줄 수 있다.


<!DOCTYPE html>
<html>
  <body>
    <div id="root"></div>
  </body>
  <script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script>
  <script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
  <script type="text/babel">
    function Btn({ text, big }) {
      return (
        <button
          style=
        >
          {text}
        </button>
      );
    }
    function App() {
      return (
        <div>
          <Btn text="Save Changes" big={true} />
          <Btn text="Countinue" big={false} />
        </div>
      );
    }
    const root = document.getElementById("root");
    ReactDOM.render(<App />, root);
  </script>
</html>


컴포넌트의 괄호 안에 props를 적어준다.
prop의 이름은 마음대로 설정할 수 있다.
event도 넣어줄 수 있다.




<!DOCTYPE html>
<html>
  <body>
    <div id="root"></div>
  </body>
  <script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script>
  <script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
  <script type="text/babel">
    function Btn({ text, changeValue }) {
      console.log(text, " was rendered");
      return (
        <button
          onClick={changeValue}
          style=
        >
          {text}
        </button>
      );
    }

    function App() {
      const [value, setValue] = React.useState("Save Changes");
      const changeValue = () => {
        setValue("Revert Changes");
      };
      return (
        <div>
          <Btn text={value} changeValue={changeValue} />
          <Btn text="Countinue" />
        </div>
      );
    }
    const root = document.getElementById("root");
    ReactDOM.render(<App />, root);
  </script>
</html>


이 때, 주의할 점은
렌더링 하는 부분에다가 onClick으로 넣으면 eventListener가 되는게 아니라는 점이다.
그 안에 들어가는 내용은 모두 property가 될 뿐이다.
그래서 위에 컴포넌트 안에서 onClick으로 함수를 넣어줘야 한다.


이 때 우리가 11번 째 줄에서 console.log(text, “ was rendered”) 해준 부분을 살펴보면


image


버튼은 하나만 바뀌는데 둘 다 리렌더 되는 것을 알 수 있다.
왼쪽 버튼만 바뀌고 오른쪽은 그대로니까 리렌더 될 필요가 없는데 말이다.
이럴 때는 React.memo를 사용해서 만약 props가 변경되지 않는다면 해당 컴포넌트가 리렌더되는 것을 원치 않는다고 알려줄 수 있다.





React.memo()


<!DOCTYPE html>
<html>
  <body>
    <div id="root"></div>
  </body>
  <script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script>
  <script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
  <script type="text/babel">
    function Btn({ text, changeValue }) {
      console.log(text, " was rendered");
      return (
        <button
          onClick={changeValue}
          style=
        >
          {text}
        </button>
      );
    }
    const MemorizedBtn = React.memo(Btn);
    function App() {
      const [value, setValue] = React.useState("Save Changes");
      const changeValue = () => {
        setValue("Revert Changes");
      };
      return (
        <div>
          <MemorizedBtn text={value} changeValue={changeValue} />
          <MemorizedBtn text="Countinue" />
        </div>
      );
    }
    const root = document.getElementById("root");
    ReactDOM.render(<App />, root);
  </script>
</html>


위와 같이 MemorizedBtnReact.memo() 도구를 사용해주고 괄호 안에는 위에서 만들었던 Btn 컴포넌트를 입력해준다.
이렇게 하면 우리가 만든 Btn을 기억하고있다가 변경되는 부분만 리렌더 하도록 도와줄 것이다.


image


콘솔에서 확인해 본 결과, text prop이 바뀐 버튼만 리렌더 된 것을 알 수 있다.





propTypes


마지막으로 propTypes에 대해서 알아보자.
우리가 props로 하나의 컴포넌트를 만들어서 여러가지 방법으로 재사용 할 수 있다는 점을 알았다.
하지만 실수로 prop에 다른 값을 전달했다고 생각해보자.


function App() { return (
<div>
  <Btn text="Save Changes" fontSize="{18}" />
  <Btn text="{14}" fontSize="Continue" />
</div>
); }


위처럼 예상했던 값과 전혀 다른 값을 전달했다고 가정하고 실행해보면
아래 처럼 정상적으로 실행된다.
아무런 경고나 오류도 나오지 않는다.


image


이 때, prop에 맞는 type을 입력해 줄 수 있도록 경고를 띄워줄 수 있다.
먼저 아래와 같은 script로 propTypes를 설치해준다.


<script src="https://unpkg.com/prop-types@15.7.2/prop-types.js"></script>


그리고나서 해당 컴포넌트의 각 prop들이 어떤 type을 가질 것인지 설정해준다.


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


그리고 다시 실행해보면 아래 사진처럼 실행은 되지만 친절하게 경고 문구를 띄워주는 것을 볼 수 있다.


image



💫 isRequired


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


뒤에 isRequired를 붙여주면


function App() {
  return (
    <div>
      <Btn text="Save Changes" fontSize="{18}" />
      <Btn text="Continue" />
    </div>
  );
}


이런 상황에서


image.


이런 에러를 받을 수도 있다.




💫 default value

혹은 아래처럼 props 안에서 default value를 설정해 줄 수도 있다.
(react기능은 아니다. )


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




Categories:

Updated:

Leave a comment