리액트(React)

김윤호·2023년 7월 9일
0

리액트

목록 보기
1/3
post-thumbnail

리액트란?

  • 자바스크립트 UI 라이브러리이다.

  • Single Page Application(SPA) 라이브러리이다.

    SPA란?

    싱글 페이지 애플리케이션은 말 그대로 하나의 페이지를 사용하는 애플리케이션이다.
    SPA는 서버로부터 새로운 페이지를 가져오는 것이 아닌, 하나의 페이지에서 내용을 동적으로 변경함으로써 사용자 웹앱을 의미한다.

    전통적인 웹 사이트는 페이지 하나에 전달되는 데이터의 용량이 적었다. 그래서 새로운 페이지로 이동할 때 완전히 새로운 페이지(HTML)을 서버에서 전송해주곤 했다(Multi Page Application). 이는 파일의 크기가 크지 않아 큰 문제가 존재하지 않았다. 하지만 점차 모니터는 커지고, 한 페이지에 담을 수 있는 정보가 많아지면서, 데이터의 용량이 커져갔고, 매번 새로운 페이지를 전달하는게 점점 버거워지게 되었다.

    그렇기 때문에 위 단점을 개선하고 한 페이지에 모든 정보를 담아주기 위해, SPA가 생기게 되었고 이를 감당하게 하는 언어가 Javascript/Typescript이다.

    SPA 구현 방식

    Ajax를 통한 SPA구현 방식은, 페이지 새로고침 없이 데이터가 교환되고 업데이트되는 것이다.

    기존에는 클라이언트가 최초 요청을 보내면 서버는 html 파일을 응답으로 보내고, 클라이언트가 다시 form 데이터를 전송하면 서버가 다른 html 파일을 응답으로 보내 페이지가 리로드 되는 방식이었다.

    그러나 SPA 방식은 form 작성 시 ajax를 이용해서 form 데이터의 일부를 전송하는데, 그럼 서버는 JSON 데이터를 응답으로 보내주는 식이다. 이렇듯 SPA는 화면 이동 시 필요한 데이터를 서버로부터 JSON 데이터로 전달받아 동적으로 렌더링한다.

    SPA는 컴포넌트 개념으로 작성된 페이지에 특히 적합한데, React를 사용해서 페이지가 컴포넌트 조각들로 이뤄진 페이지일 경우 컴포넌트의 내용 혹은 컴포넌트 자체를 교체하면 되기 때문에 SPA가 특히 좋다.

    SPA 장점

    • 클라이언트가 모든 페이지를 가지고 있으므로 앱과 같은 자연스러운 사용자 경험을 제공한다. 사실상 로딩 이후에는 모바일 앱과 동일한 방식으로 동작한다고 볼 수 있다.
    • 페이지를 이동 하더라도 필요한 부분(컴포넌트)만 부분적으로 교체하면 됨으로 효율성이 증가한다.
    • 서버가 해야 할 화면 구성을 클라이언트가 수행함으로 서버 부담이 경감된다.
    • 모듈화 또는 컴포넌트별 개발이 용이하다.
    • 프론트와 백이 비교적 명확하게 구분된다.
    • 앱과 웹이 동일한 서버를 이용할 수 있다.

    SPA 단점

    • 처음 접속시에 사이트 구성과 관련된 모든 리소스를 한 번에 받기 때문에 초기 구동 속도가 느릴 수 있다.
    • 데이터를 별도로 요청하고 받아와서 화면을 구성함으로 설계 방식에 따라서는 화면이 변하는 모습이 사용자에게 노출될 수 있다.
    • SPA 구조 상 데이터 처리는 클라이언트에서 하는 경우가 많은데, 중요한 비즈니스 로직이 존재한다면 사용자가 분석할 수 있다. (보안적 측면)
    • 검색엔진 최적화(SEO)가 어렵다.
  • 상태값이 변경될 때마다 UI를 자동으로 업데이트해주는 JS 라이브러리이다.

    • state, props, redux store, recoil 등의 상태값이 변경되면, 리액트가 해당 컴포넌트 함수를 자동으로 재호출하여 재렌더링 해준다.
  • 가상 DOM을 통해 변경된 부분만 효율적으로 업데이트해주는 구조를 가진 라이브러리이다.

    • 가상 DOM은 실제 DOM을 분석하여 만든 Javascript 객체이다.
      {
          type: 'div',
          props: {
              children: [
                  {
                      type: button,
                      props: {
                          children: "버튼입니다",
                          onClick: ()=>{}
                      }
                  },
                  {
                      type: input,
                      props: {children: "인풋입니다."}
                  },
                  {
                      type: CountButton,
                      props: {children: "리액트컴포넌트입니다"}
                  }
              ]
          }
      }
    • 컴포넌트의 상태값이 변경되면, 새로운 가상 DOM 객체를 만들고, 이전 가상 DOM 객체와 비교한다.
    • 최종적으로 바뀐 부분이 있을 경우, 해당 부분만 실제 DOM에 반영하여 UI를 업데이트한다.

리액트 UI 업데이트 단계

  1. 렌더 단계(Render Phase, diffing)

    1. 리액트는 렌더링 할 때마다 매번 새로운 가상 DOM을 만들고, 이전 가상 DOM과 비교하여 바뀐 부분을 탐색하고, 실제 DOM에 반영할 부분을 결정한다.
  2. 커밋 단계(Commit Phase)

    1. 렌더 단계를 거쳐 바꾸기로 결정된 부분만 실제 DOM에 반영한다.
    2. 브라우저는 변경된 실제 DOM을 화면에 paint한다.

    이 때가 didMount, didUpdate가 완료되어 useEffect가 호출되는 시점이다.

리액트를 풀어서 사용

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>

    <!-- 리액트 라이브러리 로드 -->
    <script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script>
    <script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin></script>
  </head>
  
  <body>
    <!-- 컨테이너 -->
    <div id="root"></div>

    <script>
        
      // 리액트 함수 컴포넌트
      function CountButton() {
        // useState 사용
        const [count, setCount] = React.useState(0);

        return React.createElement(
          'button', // button 태그 생성
          {
            onClick: () => {
              // 클릭 이벤트 핸들러 설정
              setCount(count + 1);
            }
          },
          count // children 설정
        );
      }

      // div#root 태그에 리액트 컴포넌트 렌더링하기
      const domContainer = document.getElementById('root');
      ReactDOM.render(React.createElement(CountButton), domContainer);

    </script>
  </body>
</html>

모듈화

실제로 리액트 개발을 할 시에는 JSX/TSX로 코딩하고, 모듈을 export, import 하는데, 이는 모두 babel과 webpack 덕분이다.

  1. Babel이 JSX를 React.createElement()로 변환해준다.
  2. WebPack이 JS, CSS 파일을 번들링하여 모듈화해준다.
profile
프론트엔드 개발자

0개의 댓글