[React] ReactJS로 영화 웹 서비스 만들기 4

전예원·2022년 1월 5일
0

React

목록 보기
4/10

💡 Props로 컴포넌트에 값에 접근하고, memo를 이용해 변하는 것만 리렌더링 되게끔 하는 것을 구현하는 방법을 공부해보자!

🔴 공부하기 위한 초기 셋팅


<!DOCTYPE html>
<html>

<body>
  <div id="root"></div>
</body>
<!-- React JS는 어플리케이션이 아주 interactive하도록 만들어주는 library 
  -> 엔진, interactive한 UI만들게 해줌
-->
<script crossorigin src="https://unpkg.com/react@17/umd/react.production.min.js"></script>
<!-- React-dom은 library또는 package인데, 모든 react element들을 HTML body에 둘 수 있도록 해줌 -->
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script>
<!-- jsx를 browser가 읽을 수 있게 babel을 이용해서 변환 -->
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
  const root = document.getElementById('root');

  function App() {
    return <div></div>
  }

  ReactDOM.render(<App />, root);
</script>

</html>

🟠 중복되는 것을 여러번 쓰면 귀찮아~!


  function SaveBtn() {
    return (
      <button style={{
        backgroundColor: "tomato",
        color: "white",
        padding: "10px 20px",
        border: 0,
        borderRadius: 10,
      }}>Save Changes</button>
    );
  }
  function ConfirmBtn() {
    return (
      <button style={{
        backgroundColor: "tomato",
        color: "white",
        padding: "10px 20px",
        border: 0,
        borderRadius: 10,
      }}>Confirm</button>
    );
  }
  function App() {
    return (
      <div>
        <SaveBtn />
        <ConfirmBtn />
      </div>
    )
  }
  • style을 속성을 두 버튼 다 주절 주절 쓰면 코드의 가독성도 떨어지고, 이런 것들이 많아지면 나중에 파일의 크기도 커질 위험이 있다. 또한 내가 오타 등의 오류를 행할 수 있고, 유지보수가 어렵다.
  • 캡슐화와 추상화를 시켜야한다.

🟡 커스텀 컴포넌트


🟤 커스텀한 속성값 가져오는 방법

  function Btn(props) {
    console.log(props);
    return (
      <button style={{
        backgroundColor: "tomato",
        color: "white",
        padding: "10px 20px",
        border: 0,
        borderRadius: 10,
      }}>
        {props.banana}
      </button>
    );
  }
  function App() {
    return (
      <div>
        <Btn banana="Save Changes" x={false} />
        <Btn banana="Continue" y={7} />
      </div>
    )
  }
  • Btn이라는 함수로 캡슐화, 추상화 시켜주었다.
  • 둘 버튼의 텍스트가 달랐는데, 커스텀 속성을 적용해서 banana에 값을 넣어서 그 값을 읽어주는 방식으로 했다.
  • props 값을 바로 불러 올 수 있는 더 간단한 방법

🟤 더 간단하게

function Btn({banana}) {
    // console.log(props);
    return (
      <button style={{
        backgroundColor: "tomato",
        color: "white",
        padding: "10px 20px",
        border: 0,
        borderRadius: 10,
      }}>
        {banana}
      </button>
    );
  }
  • banana는 객체라서 객체를 바로 불러와준다.
  • {banana}이런식으로 적어주면 된다.

🟤 속성을 여러개, 인자로 가져오면된다.

function Btn({banana, big}) {
    console.log({banana, big});
    return (
      <button style={{
        backgroundColor: "tomato",
        color: "white",
        padding: "10px 20px",
        border: 0,
        borderRadius: 10,
      }}>
        {banana}
      </button>
    );
  }
  function App() {
    return (
      <div>
        <Btn banana="Save Changes" x={false} big={true} />
        <Btn banana="Continue" y={7} />
      </div>
    )
  }
  • 파라미터로 커스텀 속성을 다 가져올 수 있다.

🟤 폰트도 삼항연산자로 변경 가능

function Btn({banana, big}) {
    console.log(banana, big);
    return (
      <button style={{
        backgroundColor: "tomato",
        color: "white",
        padding: "10px 20px",
        border: 0,
        borderRadius: 10,
        fontSize: big ? 18 : 12,
      }}>
        {banana}
      </button>
    );
  }
  function App() {
    return (
      <div>
        <Btn banana="Save Changes" x={false} big={true} />
        <Btn banana="Continue" y={7} big={false} />
      </div>
    )
  }
  • big이라는 커스텀 속성으로 bigtrue면 18px / false면 12px 이런 식으로도 작성 가능

🟢 커스텀 컴포넌트에 이벤트 리스너


  function Btn({text, onClick}) {
    return (
      <button 
      onClick={onClick}
      style={{
        backgroundColor: "tomato",
        color: "white",
        padding: "10px 20px",
        border: 0,
        borderRadius: 10,
        cursor:'pointer',
      }}>
        {text}
      </button>
    );
  }
  function App() {
    const [value, setValue] = React.useState("Save Changes");
    const changeValue = () => setValue('Revert Changes')
    return (
      <div>
        {
          // 커스텀 컴포넌트에 들어가는 onClick은 이벤트 리스너가 아니다! 그냥 prop
          // Btn 함수 안에 button 태그안에 들어가는 것이 이벤트 리스너이다.
        }
        <Btn text={value} onClick={changeValue} />
        <Btn text="Continue" />
      </div>
    )
  }
  • Btn함수에 들어가 있는 onClick이 진짜 이벤트 리스너이고, 커스텀 컴포넌트에 있는 onClick은 그냥 props이다.

🔵 memo로 리렌더링


  • <Btn text="Continue" />는 리렌더링 안되어도 되는데 리렌더링이 같이 되어버린다. 만약 코드가 길어지면 리렌더링 굳이 하지 않아도 되는데 리렌더링 하면 안좋다.
  function Btn({ text, onClick }) {
    console.log(text, 'was rendered');
    return (
      <button
        onClick={onClick}
        style={{
          backgroundColor: "tomato",
          color: "white",
          padding: "10px 20px",
          border: 0,
          borderRadius: 10,
          cursor: 'pointer',
        }}>
        {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} onClick={changeValue} />
        {
          // props가 변하지 않으면 리렌더링 안되게 할 수 있다.
          // 하지만 props값이 바뀌면 리렌더링 해줘야한다.
          // 리렌더링 해야할 컴포넌트가 많아지면 이렇게 변화된 것만 리렌더링 되게끔 해줘야한다.
        }
        <MemorizedBtn text="Continue" />
      </div>
    )
  }
  • const MemorizedBtn = React.memo(Btn); 작성해주고, 커스텀 컴포넌트의 이름을 변경해준다.

🟣 타입 오류를 잡아내기


  • 같이 일하는 사람이 많아 질 수록, 나만 코드를 작성하는 것이 아니기 때문에, 또 실수를 할 수 있기 때문에 오류를 검사할 수 있는 코드를 작성하는 것도 중요하다.

🟤 오류 발생

  function App() {
    const [value, setValue] = React.useState("Save Changes");
    const changeValue = () => setValue('Revert Changes')
    return (
      <div>
        <MemorizedBtn text={value} fontSize={30} />
        {
          // 아래 문장은 문법 상에 문제는 없지만, 의미상의 문제가 있다.
          // 화면에는 오류 없이 보여지지만 오류인 것이다.
          // 오류를 확인할 수 있는 코드를 만들면 좋을 것 같다.
        }
        <MemorizedBtn text={14} fontSize={"Continue"} />
      </div>
    )
  }
  • 문법적으로는 문제가 없지만, 의미적으로 문제가 있다. text에 숫자가 들어가고, 폰트 사이즈에 string이 들어갔다.

🟤 오류가 생기면 경고문구 발생해주기

<script crossorigin src="https://unpkg.com/react@17.0.2/umd/react.development.js"></script>

🟤 PropTypes 작성

  function Btn({ text, fontSize }) {
    return (
      <button
        style={{
          backgroundColor: "tomato",
          color: "white",
          padding: "10px 20px",
          border: 0,
          borderRadius: 10,
          cursor: 'pointer',
          fontSize,
        }}>
        {text}
      </button>
    );
  }
  Btn.propTypes = {
    text: PropTypes.string,
    fontSize: PropTypes.number,
  };
  function App() {
    const [value, setValue] = React.useState("Save Changes");
    const changeValue = () => setValue('Revert Changes')
    return (
      <div>
        <Btn text={value} fontSize={30} />
        <Btn text={14} fontSize={"Continue"} />
      </div>
    )
  }
  • textstring, fontSizenumber로 지정해줬다.
  • 안지키면 이렇게 경고(오류)가 뜬다
  • 수정해주었더니 경고가 사라진다.

🟤 .isRequired 속성

  • 진짜 꼭 있어야 하는 속성은 뒤에 .isRequired를 작성해준다.
  Btn.propTypes = {
    text: PropTypes.string.isRequired,
    fontSize: PropTypes.number,
  };
  function App() {
    const [value, setValue] = React.useState("Save Changes");
    const changeValue = () => setValue('Revert Changes')
    return (
      <div>
        <Btn text={value} fontSize={30} />
        <Btn fontSize={14} />
      </div>
    )
  }
  • .isRequired를 작성해 준 속성이 없으면 경고 문구가 뜬다.

⚪️ 폰트 기본 값 정해놓기 (JS기능)


  function Btn({ text, fontSize = 12 }) {
    return (
      <button
        style={{
          backgroundColor: "tomato",
          color: "white",
          padding: "10px 20px",
          border: 0,
          borderRadius: 10,
          cursor: 'pointer',
          fontSize,
        }}>
        {text}
      </button>
    );
  }
  Btn.propTypes = {
    text: PropTypes.string.isRequired,
    fontSize: PropTypes.number,
  };
  function App() {
    const [value, setValue] = React.useState("Save Changes");
    const changeValue = () => setValue('Revert Changes')
    return (
      <div>
        <Btn text={value} fontSize={30} />
        <Btn text={'Continue'} />
      </div>
    )
  }
  • { text, fontSize = 12 }이렇게 작성해 주면, 폰트 사이즈 속성이 없으면 자동으로 12px이 적용이된다.
profile
앞으로 나아가는 중~

0개의 댓글