C.W.K.
Stream
Lesson 03 of 07 · published

React 19 Action 과 Server Component 타입

~11 min · frameworks, react, react-19, actions, server-components

Level 0Curious
0 XP0/93 lessons0/23 achievements
0/100 XP to next level100 XP to go0% complete
"React 19 가 Action 추가하고 Server Component 의 타입 tighten. TypeScript 이야기가 마침내 완전해."

React 19 의 Action

React 19 가 Action 도입 — form submission, 데이터 mutation, pending state 처리하는 async 함수. <form action={createPost}> 가 action 을 form 에 연결. Action 이 `FormData` 받고, 처리, framework 가 pending state 관리.

useTransition, useOptimistic, 새 useActionState 같은 hook 이 Action 과 통합해서 optimistic update 와 form state 의 ergonomic 패턴 줘. TypeScript 가 이거 다 box 에서 옳게 타입.

Server Component — JSX 반환하는 async 함수

Server Component 가 server 에 도는 React component. TypeScript 에선 JSX 반환하는 `async function` 의미. export default async function Page() { const data = await fetchData(); return <div>{data.title}</div> } — 함수가 async, 직접 await 가능, TypeScript 가 return 을 `Promise` 로 타입.

Client Component 가 동기 유지. 파일을 top 의 `'use client'` 로 표시하면 그 안 모든 게 브라우저에 돈다는 뜻. Compiler 가 다르게 다룸: server component 가 async 가능; client component 가 hook 쓸 수.

분할이 경계에서

Server component 가 client component 를 child 로 render 가능. Client component 가 server component 직접 import 못 함 (server 코드가 브라우저에 말 안 되니까). TypeScript 타입이 이 분할 반영 — 대부분 그냥 작동, 근데 너가 line 넘으면 에러 메시지가 충분히 명확해서 fix 가능.

React 19 + TypeScript 가 modern React stack. Mutation 엔 Action, 데이터엔 Server Component, interactivity 엔 Client Component. 타입이 셋 다 통해 옳게 흐름.

Code

React 19 — Server Component, Client Component, Action·tsx
// Server Component — async 함수, 'use client' 없음.
export default async function PostsPage() {
  const posts = await fetchPosts();
  return (
    <div>
      {posts.map((p) => <PostCard key={p.id} post={p} />)}
    </div>
  );
}

// Client Component — top 의 'use client', hook 쓸 수.
'use client';
import { useState } from 'react';

export function LikeButton({ postId }: { postId: number }) {
  const [liked, setLiked] = useState(false);
  return (
    <button onClick={() => setLiked(!liked)}>
      {liked ? '❤️' : '🤍'}
    </button>
  );
}

// Action — async 함수, FormData 처리 가능.
async function createPost(formData: FormData) {
  'use server';
  const title = formData.get('title') as string;
  await db.posts.create({ title });
}

export function NewPostForm() {
  return (
    <form action={createPost}>
      <input name="title" />
      <button type="submit">Create</button>
    </form>
  );
}

External links

Exercise

작은 post-생성 flow 스케치: post 나열하는 Server Component, dialog 여는 'New Post' 버튼의 Client Component, post 만드는 Action. 각 함수 적절히 타입. Action 의 return value 를 setState 에 전달 같은 실수 타입이 잡는지 확인.
Hint
Server Component: JSX 반환 async 함수. Client Component: 'use client', useState 사용. Action: 'use server', FormData 받음. 허용된 경계 밖에서 Action 호출 시도하면 TypeScript 가 잡음.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.