Day-18 메인캠프 Section 02

Cold_Rain·2024년 9월 29일

SeSAC - 프로그램🌱

목록 보기
5/13
post-thumbnail

1. React 페이지 이동(React-Router)

1-1. React의 SPA

  • 리액트의 장점 중 하나인 SPA(Single Page Application)를 이용하여 a태그와 같은 전체 페이지 리로드 방식보단 컴포넌트만 바꿔서 빠르게 화면을 전환하는 장점이 있다.
  • 이를 근거로 React에서는 전통적인 페이지 리로드는 권장되지 않으므로 <a> 태그 대신 Link 컴포넌트를 사용하는 것이 좋음.

SPA의 특징

  1. 단일 HTML 파일: React SPA는 하나의 HTML 파일을 로드하고나서 페이지를 다시 로드하지 않고도 애플리케이션 내에서 자유롭게 화면을 전환할 수 있다.

  2. 빠른 페이지 전환: 페이지를 전환할 때 서버로부터 전체 페이지를 다시 로드할 필요가 없으므로 서버 왕복 시간이 없고 빠르게 화면을 업데이트할 수 있다.

  3. 클라이언트 측에서 처리: 페이지 이동, 상태 관리, 렌더링은 대부분 클라이언트(브라우저)에서 처리되어 서버는 필요한 데이터만 제공하는 역할을 한다.

  4. React Router: 클라이언트 사이드 라우팅을 처리하기 위해 react-router와 같은 라이브러리가 자주 사용된다. 이를 통해 URL이 변경될 때마다 특정 컴포넌트를 렌더링할 수 있다.

1-2. React-Router 설치하기

  • React-Router의 공식문서에 들어간다.
  • react-router-dom # always need this!을 터미널에 입력해줌.
  • package.json에도 설치된 것을 확인할 수 있다.

1-3. React-Router 사용하기

  return (
    <>
      <div>Aaa 페이지 입니다.</div>

      {/* 1. 리액트의 이동방식: 현재페이지에서 JS로 태그만 바꿔치기 => SPA */}
      <Link to="/bbb">Bbb 페이지로 가는 기능</Link>

      {/* 2. 고전HTML 이동방식: html페이지 새로접속함(느림) => MPA */}
      <a href="/bbb">Bbb 페이지 이동</a>
    </>
  );
-------------------------------------
import { createBrowserRouter, RouterProvider } from "react-router-dom";
import Aaa from "./routes/aaa";
import Bbb from "./routes/bbb";
const 철수의페이지목록 = createBrowserRouter([
  {
    path: "/",
    element: <App />,
  },
  {
    path: "/aaa",
    element: <Aaa />,
  },
  {
    path: "/bbb",
    element: <Bbb />,
  },
]);

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<RouterProvider router={철수의페이지목록} />);
  • Link를 사용하기 위해서는 import { Link } from "react-router-dom"; 을 임폴트 해줘야 한다.

  • index.js 에서도 import 똑같이 해주고 페이지 목록을 배열형태로 만들어 주기 위해 철수의 페이지 목록 같은 변수형태로 만들어준다.

2. setState의 원리

2-1. state 리렌더

  • React에서 state가 변경될 때마다 컴포넌트는 리렌더링된다. 하지만 setState는 비동기로 작동 하기 때문에 변경되면 임시 저장소에 모아두었다가 한번에 렌더링하게 된다.

리렌더 되는 경우

1. 새로운 props가 들어오는 경우

2. 부모 컴포넌트가 렌더링 될 경우

3. 강제 업데이트(forceUpdate)가 실행될 경우

4. state가 변경될 경우

2-2. setState의 동작 원리 3단계

1 ) 비교 (Comparison)

  • setState를 호출하면, 리액트는 이전 상태와 새로운 상태를 비교하기 시작

  • 상태가 변경되었는지 확인하기 위해 얕은 비교(shallow comparison)를 수행

  • 예를 들어, 객체의 상태가 변경될 경우 리액트는 객체의 참조(reference)를 비교하여 변경 여부를 판단

2 ) 변경 (Update)

  • 상태 변경이 필요하다고 판단되면, 상태를 비동기적으로 업데이트한다.

  • 상태가 즉시 변경되는 것이 아니라, 비동기 큐에 상태 변경 요청이 쌓이게 된다.그러므로 setState를 여러 번 호출하더라도 성능을 최적화하기 위해 한 번에 배치(batch)하여 업데이트한다.

  • 이 과정은 리액트의 내부 스케줄러에 의해 관리된다. 이런 비동기적 특성 때문에 setState를 호출한 직후의 상태 값은 바로 반영되지 않을 수 있다.

3 ) 렌더 (Render)

  • 상태가 변경된 후, 리액트는 해당 컴포넌트를 다시 렌더링한다.

  • 변경된 상태값을 기반으로 새로운 UI가 만들어진다. 효율적으로 DOM을 업데이트하기 위해 변경된 부분만 렌더링한다.

  • 결론적으로 가상 DOM(Virtual DOM)과 실제 DOM을 비교하여 변경된 부분만 실제 DOM에 적용하는 방식

2-3. setState 응용 예제

import React, { useState } from 'react';

export default function StateExample() {
  const [counter1, setCounter1] = useState(0); // 기본 상태 업데이트 방식
  const [counter2, setCounter2] = useState(0); // 함수형 업데이트 방식

  const handleClick = () => {
    // 일반 상태 업데이트 방식 (동일한 상태를 참조함)
    setCounter1(counter1 + 1);
    setCounter1(counter1 + 1);
    setCounter1(counter1 + 1);

    // 함수형 업데이트 방식 (이전 상태값을 기반으로 업데이트)
    setCounter2(prevCounter => prevCounter + 1);
    setCounter2(prevCounter => prevCounter + 1);
    setCounter2(prevCounter => prevCounter + 1);
  };

  return (
    <div>
      <h1>State Example</h1>
      <div>
        <h2>Counter 1 (기본 업데이트)</h2>
        <p>{counter1}</p>
      </div>
      <div>
        <h2>Counter 2 (함수형 업데이트)</h2>
        <p>{counter2}</p>
      </div>
      <button onClick={handleClick}>Update Counters</button>
    </div>
  );
}

counter1 (기본 상태 업데이트 방식)

  • setCounter1(counter1 + 1)이 3번 호출되었지만 모두 동일한 counter1 값을 참조한다.
  • 한 번 클릭할 때마다 counter1 값은 1만 증가한다. 그 이유는 setState 함수는 비동기적으로 동작해서 즉시 실행되지 않고, 요청이 완료될 때까지 잠시 대기한다.
  • 결론적으로 setCounter1(counter1 + 1)를 호출하면 counter1 값이 즉시 증가하는 것이 아니라, React는 해당 상태 업데이트를 예약해서 바로 적용되지 않기 때문에 3이 아닌 1이 보여지게 되는 것

counter2 (함수형 업데이트 방식)

  • setCounter2(prevCounter => prevCounter + 1)은 함수형 업데이트 방식을 사용해 최신 상태(prevCounter)를 기반으로 값을 계산한다.
  • 결론적으로 각 호출이 가장 최신의 상태 값을 사용하게 되어 한번 클릭하면 counter2 값은 3씩 증가하게 된다.
profile
프로그래밍 공부하는 찬우입니다👋

0개의 댓글