jtwjs Dev Wiki
  • DEV_ROAD
    • 💪🏻 생존하기
    • Week 1
      • 개발 환경 세팅
      • 타입스크립트
      • 리엑트
      • Testing Library
      • Parcel & ESLint
    • Week 2
      • JSX
      • Virtual DOM
    • Week 3
      • React Component
      • React State
    • Week 4
      • Express
      • Fetch API & CORS
      • React Hook
      • useRef & Custom Hook
    • Week 5
      • TDD
      • React Testing Library
      • MSW
      • Playwrite
      • Snapshot
    • Week 6
      • Separtion of Concerns
      • Principle
      • DI, (Dependency Injection)
      • Reflect-metadata
      • TSyringe
      • External Store
      • Follow Redux
      • usestore-ts
      • useSyncExternalStore
    • Week 7
      • Routing
      • Routes
      • Router
      • Navigation
    • Week 8
      • Design System
      • Style Basics
      • CSS-in-JS
      • Styled-Components
      • Global Style & Theme
    • Week 9
      • 개발하기 전 준비
      • 상품 목록 페이지
      • 상품 상세 페이지
      • 장바구니 페이지
    • Week 10
      • 로그인
      • 로그아웃
      • 회원가입
      • 주문 목록 & 주문 상세
    • Week 11
      • 배송 정보 입력
      • 포트원 결제 요청
      • 배송 및 결제 정보 전달
    • Week 12
      • 관리자 웹사이트개발시작
  • DEV_NOTE
    • TypeScript
      • 기본적 문법
        • Enum
        • 다형성
          • Untitled
        • 구조적 타이핑
        • 제너릭 타입
        • 컨디셔널 타입
        • 함수 메서드 타이핑
        • infer로 타입스크립트의 추론 직접 활용
        • 재귀 타입
        • 템플릿 리터럴 타입
        • 추가적인 타입 검사 satisfies 연산자
        • 타입스크립트 건망증
        • 원시 자료형에도 브랜딩 기법 사용 가능
        • 타입 좁히기
        • 유용한 타입 만들기
        • 데코레이터 함수
        • 앰비언트 선언도 선언 병합이 된다.
        • 앰비언트 선언도 선언병합이 된다.
    • Testing
      • Unit Testing
      • 단위 테스트의 두 분파
      • 좋은 단위 테스트를 구성하는 4대 요소
      • 테스트 대역과 식별할 수 있는 동작
      • 단위 테스트 스타일
      • 가치 있는 단위 테스트를 위한 리팩토링
      • 통합 테스트
      • Cross Browsing Testing
      • 기능 테스트 종류
      • React Testing Pattern
      • 프론트엔드 테스트 입문
        • 테스트 범위
        • 단위 테스트 검증
        • Mock
        • UI 컴포넌트 테스트
        • 테스트 커버리지
        • 웹 통합 테스트
        • MSW
        • 스토리북
        • 시각적 회귀 테스트
        • E2E 테스트
        • Github Actions 설정
        • 깃허브 액션에서 E2E
      • 시프트 레프트
        • 테스트 기본중의 기본
        • 단위 테스트
        • 코드 복잡도
        • 리팩터링
        • 코드 리뷰
        • 통합 테스트 패턴
        • 시스템 테스트의 자동화
        • 탐색적 테스트
      • Test Tip
      • vitest
      • playwright
      • Test Data Generator
      • MSW
    • Algorithm
      • coding test
      • Data Structure
    • Next.js
      • Data Fetching
      • Hydration
      • Next 13
      • Optimization
      • Next 15
    • Tailwind
      • Tailwind CSS
      • Theme
      • Directives
      • Tool
      • Design System
    • Storybook
      • Storybook
      • CSF3
      • CDD
      • Headless Component
    • Funtional Programming
      • 함수형 프로그래밍
      • 참조 투명성
      • 부수효과
      • 함수 합성
      • 제너릭 타입 활용하기
      • 암묵적 입출력
      • 액션과 계산, 데이터
      • 계층형 설계
      • 호출 그래프
      • 함수형 설계
      • 불변성
      • 일급 함수
      • 함수형 도구
    • Git
      • Github Actions
      • Conflict
      • Branch 전략
    • Contents Format
      • Audio
    • 3D Graphic
      • 3D keyword
      • Three.js
      • Geometry
      • Material
      • Light
      • Camera
      • Decal
      • Rotation
      • Text
      • Shadow
      • Fog
      • Post Processing
      • Animation
      • Math
        • Vector Space
        • 벡터의 연산
        • 회전 계산
      • 3D 컨텐츠가 만들어지는 과정
      • R3F
      • Env
      • Scene
      • Transform
      • R3F
      • Interaction & Raycast
      • Rendering Algorithnm
      • Blender
      • Blender
    • Accessibility
      • 접근성이란
    • Interactive Web
      • Parallax
      • Canvas
      • requestAnimationFrame
      • Effect
      • HSL
      • React.js + Canvas
      • Matter.js
    • AWS
      • DevOps
      • Amplify
      • S3
      • 클라우드 컴퓨팅
        • 온프레미스와 클라우드
        • 클라우드 도입효과
        • 클라우드 컴퓨팅의 범위
        • 컴퓨팅 옵션
          • EC2 - Virtual Machin
          • ECS, EKS - Container
          • Lambda - Serverless
        • 네트워크 가상화
        • 스토리지
        • 데이터베이스
        • 데이터 수집
        • 머신 러닝 영역
        • IoT 영역
        • 블록체인 영역
      • 클라우드 아키텍처 설계
    • Network
      • Web Server & WAS
    • System Design
      • System Design
      • Component
      • 의존성을 배제한 개발
      • Error Handling
      • Architecture
        • 모노로틱 아키텍처
        • Clean Architecture
        • Layered Architecture
        • 이벤트 기반 아키텍처
      • 상황을 파악하는 메타인지
      • 중복 문제 해결하기
      • Monorepo Arhitecture
        • 모노레포 운영과 트러블슈팅
        • Module Federation
      • 코드 병목지점
      • API 대응
      • 공통 코드
      • Infra 구축
      • 모듈 기반의 개발 방식
      • Design System
        • 최소 수준의 아키텍처 설정
        • 더 효율적인 디자인시스템 만들기
        • 디자인 시스템과 UI 라이브러리 목적
        • 디자인 토큰
      • 효율적인 업무
        • 업무 프로세스 병목 파악
      • Clean Code
      • Design Pattern
        • CQRS Pattern
        • Strangler Fig Pattern
        • 데코레이터 패턴
        • 커맨드 패턴
        • 전략 패턴
        • 옵저버 패턴
      • A/B 테스팅
      • 대규모 리엑트 웹앱 개발
        • 복잡성 관리
        • 모듈성
        • 성능
        • 디자인 시스템
        • 데이터 패칭
        • 상태 관리
        • 국제화
        • 코드 조직화하기
        • 개인화 A/B 테스팅
        • 확장 가능한 웹 아키텍처
        • 테스팅
        • 툴링
        • 기술적 마이그레이션
        • 타입스크립트
        • 라우팅
        • 사용자 중심 API 디자인
        • 리액트 미래
    • Performance
      • React DevTools
      • Component 최적화
      • Page Load
      • API
    • MFA
      • MSA
      • MFA 도입하기
      • Monorepo
        • Monorepo Tool
        • Yarn Berry Workspace
        • Turborepo
      • MFA Composition
      • SPA 통합
      • Design System
      • Package Manager
        • Yarn
        • pnpm
      • Transpiler & Bundler
        • Babel
        • Rollup
        • esbuild
        • swc
        • Webpack
        • Vite
      • 분해와 통합을 위한 여러 기술 비교
    • State Management
      • Zustand
    • React v18
      • Automatic batching
      • Suspense
      • Transition
    • SEO
      • Search Engine Optimization
      • Open Graph Element
      • Metadata
    • FE Develop
      • Scrubbing
      • Clipboard
    • Refactoring
      • 리팩토링 깊게 들여다보기
      • 긴 코드 조각내기
      • 타입 코드 처리하기
      • 유사한 코드 융합하기
      • 데이터 보호
      • 코드 추가 및 제거
    • OAuth 2.0
    • Analytics
      • Mixpanel
    • ETC
      • VSCode
    • React Hook In Action
      • useContext & Provider
      • 커스텀 훅
      • 코드 분할하기 with Suspense, lazy
      • Suspense와 이미지 적재하기
      • useTransition, uesDeferredValue
      • SuspenseList
Powered by GitBook
On this page
  • 리액트 미래 v19
  • 새로운 훅과 API
  • useTransition
  • useActionState
  • <form> 액션
  • useFormStatus
  • useOptimistic with 낙관적 업데이트
  • use API
  • 리엑트 컴파일러
  • 등장 배경
  • 메모이제이션
  • 외부 함수 메모이제이션
  • 리엑트 컴파일러 핵심 가정
  • 사용해보기
  • 리액트 서버 컴포넌트
  • 서버 컴포넌트란
  • 서버 액션 (서버 함수)
  • 장점
  1. DEV_NOTE
  2. System Design
  3. 대규모 리엑트 웹앱 개발

리액트 미래

Previous사용자 중심 API 디자인NextPerformance

Last updated 1 month ago

리액트 미래 v19

새로운 Hook, API, 리엑트 컴파일러, 리엑트 서버 컴포넌트

  • useMemo, useCallback, memo → React Compiler

  • forwardRef → ref is a prop

  • React.lazy → RSC, promise-as-child

  • useContext → use(Context)

  • throw promise → use(promise)

  • <Context.Provider> → <Context>

새로운 훅과 API

  • 시간이 걸릴 수 있는 상태 업데이트에 대기 표시

  • 해당 훅을 활용해서 비동기로 데이터를 가져오는 동안 로딩 인디케이터나 플레이스홀더의 렌더링을 관리할 수 있음

    • 직접 대기/로딩 상태 속성을 만들고 관리하지 않아도 된다.

  • 전환 진행 여부를 나타내는 '대기' 플래그를 제공함

const Component = () => {
  const [formState, setFormState] = useState(...)
  const [isPending, startTransition] = useTransition();
  
  const formAction = (e) => {
    e.preventDefault();
    
    startTransition(async () => {
      try {
        const result = await submitForm();
        setFormState(result);
      } catch (err) {
        setFormState({
          message: "Failed to complete action"
        })
      }
    })
  }
  
  return (
    <form onSubmit={formAction}>
      {isPending ? <h4>pending...</h4> : null}
      {formState?.message && (
        <h4>{formState.message}</h4>
      )
    </form>
  )
}

비동기 전환을 사용하는 함수는 이제 액션이라 부른다.

액션을 관리하는 훅들이 다수 존재함 (useActionState, ...)

폼 액션의 결과에 기반해 상태를 업데이트 가능

  • 매개변수

    • 하나의 액션 함수: 이 함수는 폼 액션이 트리거되면 실행됨

    • 하나의 초기 상태 객체: 사용자 상호작용이 일어나기 이전의 시작 상태를 설정

    • (옵션) 하나의 영구 링크: 이 링크는 이 폼이 수정할 고유한 페이지 URL을 가리킴

  • 반환값 (튜플)

    • 폼의 현재 상태

    • 폼 액션을 트리거하는 함수

    • 액션의 대기 여부를 나타내는 하나의 불리언값

import { useActionState } from 'react';

export const Component = () => {
  const [state, dispatch, isPending] = useActionState(action, initialState, permalink)
  //...
}

<form> 액션

<form>태그는 이제 action prop을 가짐

폼이 제출되었을 때 트리거되는 액션 함수

import { useActionState } from 'react';

const submitForm = async () => {/.../}

const action = async (currentState, formData) => {
  try {
    const result = await submitForm(formData);
    
    return { message: result };
  } catch {
    return { message: "Failed to complete action" }
  }
}

export const Component = () => {
  const [state, dispatch, isPending] = useActionState(action, null);
  
  return (
    <form action={dispatch}>
      <input {...} disabled={isPending} />
      <button type="submit" disabled={isPending}>
        Add todo
      </button>
      
      {state.message && <h4>{state.message}</h4>}
    </form>
  )
}

중첩된 컴포넌트 안에서의 폼 제출로부터 상태 정보에 접근할 수 있도록 디자인됨 (useContext 같은 너낌)

  • Context API를 사용하여도 폼 상태나 다른 데이터를 자손으로 전달할 수 있긴하지만 "action은 이런식으로 사용하라"라고 리엑트답지 않게 만들어둔것 같다.

  • 상위에서 <form action={action}>, 하위에서 상위 액션의 상태를 가져오기 위해 사용되는 훅

  • useFormStatus를 사용하면 직접 컨텍스트를 설정하지 않고 폼과 관련된 상태 관리를 직접적으로 간소화 가능

import { useFormStatus } from 'react';

export const NestedComponent = () => {
  const { pending, data, method, action } = useFormStatus();
  
  return (...)
}


export const App = () => {
  return (
    <form action={action}>
      <NestedComponent />
    </form>
  );
}

낙관적 업데이트란 비동기 조작과 UI 업데이트가 해당 조작의 실제 성공을 확인하기 전 이미 성공한것으로 가정

  • 사용자 경험 향상 기법 중 하나

  • 사용자 인터렉션 후 서버 응답을 기다리지 않고 결과를 사용자에게 즉각적으로 반영하는 것

  • 업데이트가 종료되거나, 에러가 발생하면 리엑트는 자동으로 템플릿에서 사용된 optimisticMessage를 message prop의 값으로 바꾼다.

export const Component = ({
  message,
  updateMessage
}) => {
  const [inputMessage, setInputMessage] = useState("");
  
  const [optimisticMessage, setOptimisticMessage] = useOptimistic(message);
  
  const submitForm = async (e) => {
    e.preventDefault();
    const newMessage = inputMessage;
    
    // API 변경 트리거 전 낙관적으로 값을 설정
    setOptimisticMessage(newMessage);
    
    // API 제출이 해결되면 상태를 업데이트
    const updatedMessage = await submitToAPI(newMessage);
    updateMessage(updatedMessage);
  }
  
  return (
    <form onSubmit={submitForm}>
      {/*낙관적 값 보여주기*/}
      <p>{optimisticMessage}</p>
      {...}
    </form>
  )
}

use API

컨텍스트, 프로미스 같은 리소스로부터 값을 읽을 수 있는 다양한 방법 제공

  • <Context.Provider> 를 사용하지 않고 <Context> 를 직접 렌더링할 수 있게 변경됨

  • 더이상 컨텍스트 값을 읽기위해 useContext 훅을 사용하지 않고 use() 사용

  • use()는 서스펜스 및 에러바운더리와 매끄럽게 통합되어 프로미스를 읽을 수 있음

const MessageContext = createContext();

const App = () => {
  const [message, setMessage] = useState("world");
  
  return (
    <MessageContext value={{ message, setMessage }}>
      {...}
    </MessageContext>
  )
}


// use
const NestedChild = () => {
  const { message, setMessage } = use(MessageContext);
}

use()는 기존 리엑트 훅의 규칙과 달리 조건문이나 반복문 내부에서도 사용 가능

function HorizontalRule({ show }) {
  if (show) {
    const theme = use(ThemeContext);
    return <hr className={theme} />;
  }
  return false;
}

리엑트 컴파일러

리액트 팀이 만든 실험적 컴파일러

최적화 프로세스를 자동화함으로써 앱 성능을 크게 개선하는것을 목적으로 함

  • 성능 튜닝의 책임을 오롯이 개발자가 지는게 아닌 프레임워크도 어느정도 지는 식 (패러다임 이동을 의미)

    • 컴포너트가 상태 및 props를 사용하는 것을 분석하여 효과적으로 리렌더링을 최적화함

    • 실제로 변경되는 부분을 의존하는 컴포넌트들만 리렌더링하도록 지능적으로 결정

  • 무엇을 메모화해야하는지에 대한 의사 결정을 자동화!

  • 최소한의 노력으로 최소한의 성능 보장

  • 가장 큰 영향을 미치는 부분에 메모이제이션이 정밀하고 효율적으로 적용되는 것을 보장

  • 리엑트 컴파일러는 useEffect 안에서의 자동 메모이제이션을 처리하지 않음 (연구 및 개발은 현재 진행형이라고 함)

리엑트 컴파일러의 메모화는 여러 컴포넌트나 훅에서 공유되지 않음

등장 배경

  • 리액트를 사용하는 개발자들은 memo, useMemo, useCallback 을 사용해서 불필요한 리렌더링, 계산을 방지하였는데 이 기법들은 효과적이지만 개발자가 직접 무엇을 언제 메모화할것인지 결정해야만 했음

  • 이 수동 프로세스는 시간도 들고 휴먼에러(실수)가 발생될 수 있는 여지가 있고, 잘못 사용하면 성능을 저하시킬수 있었음

메모이제이션

값비싼 함수 호출의 결과를 저장한 뒤 동일한 입력이 발생했을 때 캐시해 둔 결과를 반환함으로써 컴퓨터 프로그램의 속도를 높임

  • 선언적 모델

  • 컴포넌트 기반 아키텍처를 위한 DOM의 직접적인 조작을 추상화함으로써 개발자들은 UI를 일련의 명령적 업데이트가 아닌 상태의 반영으로 생각할 수 있게 됨

  • 멘탈 모델, 특히 앱 복잡성이 증가할 때의 멘탈 모델을 크게 단순화시켰음

    • 사고방식

  • useEffect의 경우 의존성 배열에 의해 본질적으로 메모화되고 컴포넌트가 마운트 된 뒤 한 번만 실행되는것이 보장됨

  • memo의 경우 컴포넌트를 메모화하여 부모가 리렌더링되었을 때가 아닌 각 컴포넌트의 속성이 변경되었을 때만 리렌더링되는것을 보장

  • useMemo는 컴포넌트 안의 모든 계산된 값을 메모화할 수 있음

  • useCallback은 컴포넌트 안의 함수 참조를 메모화

외부 함수 메모이제이션

컴포넌트 내부에서 사용되는 값비싼 외부 함수의 메모이제이션도 해결함 (컴포넌트 외부에서 선언된 함수ㅇㅇ)

  • 함수 자체를 메모이제이션 하는것은 아님

    • 리엑트는 컴포넌트와 훅만 메모화함

  • 함수 호출을 메모화함

  • 리엑트 컴파일러의 메모화는 다른 컴포넌트나 훅에서 공유를 하지 않기 때문

컴파일러의 기능을 최대한 활용하고 최적의 성능을 보장하기 위해 이 가정들을 이해하고 준수해야함

유효한 시멘틱 자바스크립트

  • 컴파일러가 처리하는 코드가 유효하며, 시맨틱 자바스크립트 원칙을 따른다고 가정

  • 즉, 유효한 자바스크립트 문법을 사용하는지

널러블 값의 안전한 처리

  • 안정성을 보장하기 위해, 컴파일러는 코드를 처리하기 전에 해당 코드가 널러블값과 옵셔널 값에 대한 안전 확인을 포함한다고 가정함

  • TS 설정에서 strictNullChecks 컴파일러 옵션을 활성화해 널러블 및 옵셔널 값을 안전하게 처리함을 보장할 수 있음

/*
  nullableProperty가 null 혹은 undefined가 아니면 'foo' 속성에 접근한다.
*/
if (object.nullableProperty) {
  return object.nullableProperty.foo
}
  • 혹은 옵셔널 체이닝을 사용하여 조건 확인 수행

return object.nullableProperty?.foo

리액트 규칙을 따름

  • 컴포넌트와 훅이 리액트 안에서 의도된 디자인 패턴과 일관되게 사용되었음을 보장하는것들이 포함됨

    • 컴포넌트와 훅은 순수해야함 → 같은 입력이 들어오면 같은 결과를 반환해야함

    • 컴포넌트는 멱등성을 가져야함 → 같은 입력으로 몇번을 실행해도 결과가 변하지 않아야함

    • props와 상태는 불변하게 다뤄져야함

    • 훅은 '최상위 레벨', 및 리엑트 함수형 컴포넌트에서만 호출되어야함

    • ...등등

  • 컴포넌트와 훅들이 예측대로, 유지보수 가능하게 작동하는 것을 보장하는데 매우 중요

  • 그리고 컴파일러가 효과적으로 최적화를 수행하는데 필수적

  • 컴파일러는 이 규칙을 위반한 코드를 만나면 코드가 컴파일되도록 강제하는 시도를 하지 않음

    • 안전하게 건너뛰고 나머지 코드를 계속 컴파일함

사용해보기

  • 메타에선 프로덕션에 사용중이지만, 아직 공식적으로는 실험 단계

    • 아직은 폭넓게 도입될 만큼 안정적이지 않다는것

리액트 서버 컴포넌트

서버 컴포넌트를 통해 서버 사이드 렌더링을 리액트 아키텍처에 매끄럽게 통합 가능

  • 서버 사이드 렌더링 흐름은 간단히 페이지 진입 후 서버에서 HTML를 반환(렌더링) 후 클라이언트가 API 요청을 다시 서버로 보내 데이터를 가져와야 한다 (데이터 가져오기)

    • 즉, 렌더링과 데이터 가져오기를 별도로 처리하는게 불-편

    • 서버 사이드 데이터 가져오기를 직접적으로 컴포넌트 렌더링과 통합한 리액트 표준이 필요해짐 → 서버 컴포넌트

  • 서버의 첫 응답에 데이터를 가져온다면 보다 효율적이고 프로세스를 간소화시켜 요청을 여러번 보낼 필요가 줄어들게됨

    • 이전 next.js는 getServerSideProps라는 함수를 사용해 해결했음

  • 리액트 서버 컴포넌트는 강력한 이익을 제공하며 점점 확산될것이지만, 리액트 생태계에 추가된 또 하나의 도구일 뿐, 기존 패턴들을 반드시 대체해야하는 것은 아님

  • 개발자들은 프로젝트 요구사항에 맞는 최적의 접근 방법을 찾을 것

Reference

서버 컴포넌트란

  • 리액트의 새로운 기능

  • 상태를 갖지 않는 컴포넌트

  • 서버에서 실행됨

  • 특정 계산과 데이터 가져오기 부담을 클라이언트에서 서버로 옮길 수 있음 (서버의 컴퓨팅 파워가 더 높으니 개이득)

  • 클라이언트로 전달되는 코드양을 줄이고, 로딩 시간을 줄임 → 앱 사용성 개선

  • 서버에서 배타적으로 실행되기에 전통적인 클라이언트 컴포넌트와 동작에 차이가 있음

클라이언트 사이드 리액트 API에 접근 불가

  • 서버에서 실행되므로 전통적인 리엑트 훅 사용 못함

  • 서버 컴포넌트에서 상호작용을 도입하려면 상호작용을 다루는 클라이언트 컴포넌트를 활용해야함

    • 즉, 서버 컴포넌트에서 상호작용 가능한 클라이언트 컴포넌트를 자식으로 사용

반대로 클라이언트 컴포넌트에서 자식으로 서버 컴포넌트를 사용할 수 없음

  • 서버 컴포넌트는 서버에서만 실행되므로, 클라이언트 컴포넌트에서 직접 가져오면 클라이언트에서 실행할 방법이 없음

비동기 서버 컴포넌트

  • 서버 컴포넌트는 비동기로 작동할 수 있음

  • await 키워드를 사용해 데이터를 꺼낼 때까지 대기함으로써 데이터를 완전히 로딩한 뒤 컴포넌트를 렌더링 가능

  • await을 사용하지 않는 건은 데이터를 기다리지 않고 렌더링 프로세스를 진행시킴

    • 대신 Suspense 컴포넌트에 의해 비동기로 가져오고 관리됨

    • 서버에서 처리가 시작되지만 기다려지지 않으므로, 클라이언트에 비동기로 전달될 수 있음

    • use() 함수를 사용하면 컴포넌트는 서버 컴포넌트에서 전달된 프로미스를 구독하게됨

    • 결과적으로 클라이언트 컴포넌트는 서버에서 요청된 비동기 데이터를 받게 되는 순간 즉시 렌더링

    • 페이지 나머지 부분을 블로킹하지 않음

      • 점진적 향상 원칙을 내포함, 기본 컨텐츠 기능은 한 번에 제공하고, 추가적인 기능들은 점진적으로 제공

"use client";

import { use } from 'react';
import { Comment } from './Comment';

export const Comments({ commentsPromise }) {
  const comments = use(commentsPromise);
  
  return (
    comments.map((comment) => (
      <li key={comment.id}>
        <Comment {...comment} />
      </li>
    ))
  )
}

서버 액션 (서버 함수)

클라이언트 컴포넌트가 서버 사이드 함수를 직접 호출하게 할 수 있음

2024년 9월까지는 모든 서버 함수를 "서버 액션"이라고 불렀습니다. 서버 함수가 액션 프로퍼티에 전달되거나 액션 내부에서 호출되면 서버 액션이지만 모든 서버 함수가 서버 액션인 것은 아닙니다. 이 문서의 명칭은 서버 함수가 여러 용도로 사용될 수 있다는 점을 반영하여 업데이트되었습니다.

  • 이를 활용해서 때때로 서버 사이드 처리와 클라이언트 사이드의 동적 응답성의 장점을 조합할 수 있음

    • 이 프로세스는 전체 페이지 재로딩을 요구하지 않음

    • 클라이언트 사이드 상호작용의 실시간 응답성과 데이터 무결성 및 서버 사이드 동작의 처리 능력을 결합한 매끄러운 사용자 경험을 제공하게됨

  • 서버 액션은 서버 컴포넌트 안에서 "use server" 지시자를 사용해 정의함

  • 서버 컴포넌트에서 정의한 서버 액션을 props로 전달되어 클라이언트 컴포넌트에서 사용할 수 있음

import { Comments } from './Comments';
import db from './database';

const BlogPost = async ({ postId }) => {
  //...
  
  // 서버 액션
  const async upvoteAction = (commentId) => {
    "use server";
    await db.comments.incrementVotes(commentId, 1);
  }
  
  return (
    <div>
     {/*서버 액션은 props로서 아래로 전달됨*/}
     <Comments
       commentsPromise={comments}
       upvoteAction={upvoteAction}
     />
    </div>
  )
}
  • 클라이언트 컴포넌트 또한 "use server" 지시자를 선언한 파일에서 직접 서버 액션을 임포트 가능

// 별도 파일에 정의된 서버 액션
"use server";

import db from './database';

export const upvoteAction = async (commentId) => {
  await db.comments.incrementVotes(commentId, 1);
}

export const downvoteAction = async (commentId) => {
  await db.comments.incrementVotes(commentId, -1);
}

장점

서버 컴포넌트를 사용하면 서버 사이드 렌더링과 클라이언트 사이드 렌더링을 조합해 성능과 사용자 경험을 최적화 가능

성능 개선

  • RSC는 복잡한 계산과 데이터 가져오기를 서버로 넘겨서 클라이언트에 전달할 코드 양을 줄임

  • 빠른 초기 로딩 시간과 성능 개선

SEO 향상

  • 서버 사이드 렌더링은 컨텐츠가 이미 검색 엔진에서 읽을 수 있는 상태임을 보장하므로 SEO를 향상시킴

데이터 가져오기 단순화

  • RSC는 데이터 가져오기를 컴포넌트 렌더링 프로세스에 직접 통합하므로, 클라이언트는 별도의 API 호출을 할 필요가 없음

  • 이 간소화된 접근법은 클라이언트 사이드의 상태와 데이터 동기화를 관리하는 복잡성을 줄임

with 낙관적 업데이트

리액트 컴파일러는 을 이해하며, 고급 정적 분석을 활용하여 컴포넌트와 리액트 앱의 훅 사이에 메모제이션을 지능적으로 적용함

리엑트 문서에는 이를 이라 부름

에서는 여러 다른 컴포넌트들이 하나의 값비싼 함수를 사용할것으로 예상된다면, 해당 함수 자체에 대한 메모이제이션을 구현하라고 안내함

리엑트 컴파일러

리액트 컴파일러는 앱을 자동으로 최적화하는 한편, 처리 대상 코드에 대한 몇가지 에 의존함

useTransition
useActionState
useFormStatus
useOptimistic
리액트 규칙
세분화된 반응
리엑트 공식문서
핵심 가정
핵심적인 가정
React Compiler Getting Started
Successfully rolling out the compiler to your codebase
Forget About Memo
React Compiler Deep Dive
React Server Components
Server Actions
Understanding React Server Components
When to use Server and Client Components?
Making Sence of React Server Components
React Server Components: A comprehensive guide