PromleeBlog
sitemap
aboutMe

posting thumbnail
Next.js 16과 React 19의 새로운 기능들
Next.js 16 and React 19 New Features

📅

🚀

들어가기 전에 🔗

안녕하세요.
지난 3부작에 걸쳐 Next.js 16의 성능, 아키텍처, 그리고 마이그레이션 방법을 살펴보았습니다.

하지만 Next.js 16의 진정한 가치는 바로
최신 React(v19)와의 완벽한 조화
에 있습니다.
이번 번외편에서는 Next.js 16 환경에서 사용할 수 있는 React 19의 따끈따끈한 신기능들을 알아보겠습니다.
사용자 경험(UX)을 한 차원 높여줄
View Transitions
부터, 개발자를 위한
새로운 훅(Hooks)
까지 알차게 준비했습니다.

🚀

1. 부드러운 화면 전환: View Transitions 🔗

웹 앱을 쓰다 보면 페이지가 바뀔 때 '깜빡'하거나 딱딱하게 끊기는 느낌을 받을 때가 있습니다.
React 19와 Next.js 16은 브라우저의
View Transitions API
를 지원하여, 별도의 무거운 애니메이션 라이브러리 없이도 부드러운 전환 효과를 구현할 수 있게 해 줍니다.

어떻게 사용하나요? 🔗

React 19의 startTransition 은 이제 비동기 함수를 지원하며, 이를 통해 데이터가 로딩되는 동안 이전 화면을 유지하다가 부드럽게 새 화면으로 전환합니다.
app/components/TabSwitcher.tsx
'use client';
 
import { useTransition, useState } from 'react';
import { fetchTabData } from './actions';
 
export default function TabSwitcher() {
  const [isPending, startTransition] = useTransition();
  const [data, setData] = useState(null);
 
  function handleTabClick(tabId: string) {
    // [핵심] startTransition으로 상태 업데이트를 감쌉니다.
    // React는 이 작업이 완료될 때까지 UI를 차단하지 않고,
    // 브라우저의 View Transition API와 연동하여 부드러운 전환을 준비합니다.
    startTransition(async () => {
      const newData = await fetchTabData(tabId);
      setData(newData);
    });
  }
 
  return (
    <div>
      <div className="tabs">
        <button onClick={() => handleTabClick('home')}>Home</button>
        <button onClick={() => handleTabClick('settings')}>Settings</button>
      </div>
      
      {/* 데이터 로딩 중에는 투명도를 조절하는 등 시각적 피드백 제공 가능 */}
      <div style={{ opacity: isPending ? 0.5 : 1 }}>
        {data ? <Content data={data} /> : <p>Select a tab</p>}
      </div>
    </div>
  );
}

🚀

2. Server Actions 보안 강화 🔗

Next.js 16은
Server Actions
를 사용할 때의 보안을 더욱 강화했습니다.
클라이언트 컴포넌트에서 서버 함수를 import 할 때, 실수로 서버 전용 코드가 클라이언트 번들에 포함되는 것을 막기 위해
데드 코드 제거(Dead Code Elimination)
기술이 더욱 공격적으로 적용됩니다.

이게 왜 중요한가요? 🔗

개발자가 실수로 데이터베이스 비밀 키나 내부 로직이 담긴 함수를 클라이언트로 넘기는 실수를 방지해 줍니다.
Next.js 16 컴파일러는 클라이언트가 서버 액션을 호출할 때,
오직 액션의 ID만
참조하도록 코드를 최적화합니다.
app/actions.ts
'use server';
 
// 이 함수 내부의 로직(DB 접근 등)은 절대 클라이언트로 유출되지 않습니다.
export async function submitForm(formData: FormData) {
  const apiKey = process.env.API_KEY; // 서버 환경 변수
  await saveToDb(formData, apiKey);
  return { success: true };
}

🚀

3. UX를 위한 새로운 훅: useOptimistic 🔗

채팅 앱에서 메시지를 보내면, 서버 응답이 오기 전에 내 화면에는 이미 말풍선이 뜨죠?
이런
낙관적 업데이트(Optimistic Update)
를 구현하는 것은 꽤 복잡했습니다.
하지만 React 19의 useOptimistic 훅을 사용하면 아주 간단해집니다.
app/components/MessageList.tsx
'use client';
 
import { useOptimistic, useRef } from 'react';
import { sendMessage } from './actions';
 
export default function MessageList({ messages }: { messages: string[] }) {
  // [핵심] useOptimistic 훅 사용
  // optimsticMessages: 화면에 보여줄 임시 상태
  // addOptimisticMessage: 임시 상태를 추가하는 함수
  const [optimisticMessages, addOptimisticMessage] = useOptimistic(
    messages,
    (state, newMessage: string) => [...state, newMessage]
  );
 
  async function action(formData: FormData) {
    const message = formData.get('message') as string;
    
    // 1. 서버 요청을 보내기 전에 화면에 먼저 표시 (낙관적 업데이트)
    addOptimisticMessage(message);
    
    // 2. 실제 서버 요청 (실패 시 React가 알아서 상태를 롤백해 줍니다)
    await sendMessage(message);
  }
 
  return (
    <div>
      {optimisticMessages.map((m, i) => <div key={i}>{m}</div>)}
      <form action={action}>
        <input name="message" />
        <button type="submit">Send</button>
      </form>
    </div>
  );
}

🚀

4. useEffectEvent와 Activity 🔗

Next.js 16에 포함된 React Canary 기능 중 주목할 만한 두 가지가 더 있습니다.

useEffectEvent 🔗

useEffect 내부에서 어떤 값은
반응형(Reactive)
이고 싶고, 어떤 값은 그렇지 않고 싶을 때가 있습니다.
예를 들어, "채팅방이 바뀔 때만 접속 로그를 남기고 싶지만, 테마 색상은 최신 값을 쓰고 싶을 때" 유용합니다.
useEffectEvent 는 이펙트를 다시 실행시키지 않으면서 최신 값을 읽을 수 있게 해 줍니다.

Activity (Offscreen) 🔗

탭을 전환했다가 돌아왔을 때, 스크롤 위치나 입력했던 내용이 사라져서 불편했던 적 있나요?
<Activity> 컴포넌트는 화면에서 사라진 컴포넌트를
언마운트(Unmount)
하지 않고, CSS의 display: none 처럼 숨겨두면서 상태를 보존합니다.
덕분에 다시 돌아왔을 때 즉시 이전 상태를 보여줄 수 있습니다.

🚀

결론 🔗

이번 번외편을 끝으로 Next.js 16 시리즈를 마칩니다.
Next.js 16은 단순히 "빨라졌다"는 것을 넘어,
View Transitions
새로운 훅
들을 통해 사용자가 웹을 경험하는 방식 자체를 부드럽고 자연스럽게 만들 수 있는 도구들을 제공합니다.
이 기술들을 적절히 활용하여, 빠르면서도 섬세한 사용자 경험을 만들어 보시길 바랍니다.
함께해 주셔서 감사합니다.

참고 🔗