IT/React

React. ch1. 08. 리액트의 리랜더링

체계성 2021. 10. 10. 23:11

○ 바닐라 JS -> 변경으로 인해 Element를 다시 그림

    React -> 변경된 부분만 다시 그림

<!DOCTYPE html>
<html lang="en">
  <body>
    <!-- 리액트를 사용하기 위한 CDN -->
    <script
      crossorigin
      src="https://unpkg.com/react@17/umd/react.development.js"
    ></script>
    <script
      crossorigin
      src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"
    ></script>
    <script
      crossorigin
      src="https://unpkg.com/@babel/standalone/babel.min.js"
    ></script>
    <!-- jQuery 스크립트 -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

    <!-- JavaScript 스크립트 -->
    <script src="index.js"></script>

    <div id="root1"></div>
    <div id="root2"></div>
    <div id="root3"></div>
    <div id="root4"></div>
    <div id="root5"></div>

    <!-- 바닐라 JS로 element의 변화가 발생하는 경우 -->
    <script>
      // 1. 일반 function
      const rootElement1 = document.getElementById("root1");
      function random1() {
        const num1 = Math.floor(Math.random() * (10 - 1) + 1); // 1~9 추출

        const element1 = `<button>${num1}</button>`;
        rootElement1.innerHTML = element1;
      }
      // 1회 호출
      random1();
      // 반복 호출(특정 시간)
      setInterval(random1, 1000); // 특정 함수를 1000 간격으로 호출하자.

      // 1. arrow function
      const rootElement2 = document.getElementById("root2");
      const random2 = () => {
        const num2 = Math.floor(Math.random() * (10 - 1) + 1); // 1~9 추출
        const element2 = `<button>${num2}</button>`;
        rootElement2.innerHTML = element2;
      };
      // Arrow Func의 호출 방법1
      console.log(random2());
      // Arrow Func의 호출 방법2
      setInterval(random2, 1000); // 특정 함수를 1000 간격으로 호출하자.
    </script>

    <!-- 리액트 코드로 element의 변화가 발생하는 경우 -->
    <script type="text/babel">
      const rootElement3 = document.getElementById("root3");
      const random3 = () => {
        const num3 = Math.floor(Math.random() * (10 - 1) + 1);

        // const element3 = <button>{num3}</button>;
        // 다중 element가 아닌 하나의 요소만 넣을 경우 React.Fragment(<></>)는 생략 가능

        const element3 = (
          <>
            <button>{num3}</button> 
            <p>{num3}</p>
            <div>
              <a>{num3}</a>
            </div>
            <button>{num3}</button>
          </>
        );
        // {num3}는 className, style 처럼 props 인가?
        // 그렇다! -> <button children={num3} /> 처럼 children이라는 props(속성)이다.
        // <button>{num3}</button>   =   <button children={num3} />
        
        ReactDOM.render(element3, rootElement3);
      };
      console.log(random3);
      setInterval(random3, 1000); // 특정 함수를 1000 간격으로 호출하자.

      // F12에서 버튼 요소를 보면,
      // 기존 자바스크립트 코드로는 상위 div, 하위 button 요소가 함께 깜빡이며 변경된다.
      // 부모에게 자식 요소의 변화 효과가 전파된다.
      // 버튼 자체를 계속 새로 만들고 있는 상황이다.

      // 리액트에서는 button 요소만 깜빡이며 변경된다.
      // 부모에게 자식 요소의 변화 효과가 전파되지 않는다.

      // 버튼이 있는 페이지에서 tab을 누르면 버튼에 focus가 맞춰지는데
      // 버튼 내부 숫자가 변하면서 focus를 잃게 된다. (리액트에선 focus 유지)

      // 즉, 리액트에서 버튼의 focus가 남아 있다는 것은
      // 버튼 요소가 새로 만들어진게 아니라 버튼 내부 글자만 바뀌고 있는 것이다.
      // 리액트의  장점! 
      // 특정 요소를 타게팅해서 그 요소만 변화시키기 때문에 효율적이다. = 리랜더링

      // 여러 요소가 나열된 경우, 특정 요소가 사라지고 다시 생기면,
      // 그 속에서 배치와 간격이 흐트리지고 다시 정돈되는데 리액트에서는 그 현상이
      // 방지되는 이점이 있다. (re-flow,re-paint, rer-endering)
    </script>
  </body>
</html>