개발 공부 일지/Next

[Next] Event handlers cannot be passed to client component props 오류 해결

dev-hpk 2025. 1. 15. 21:21

Next.js에서 button 요소에 onClick 이벤트 핸들러를 전달하려고 하는데 아래와 같은 에러가 발생했습니다.

const handleClick = async () => {
    const query = await getDoc(doc(db, "사용자", "zSen5y9LJazULo2C3atN"));
    console.log(query.data());
  };

  return (
    <div>
      <button
        className='bg-black text-white p-2 rounded-md'
        onClick={handleClick}
      >
        데이터 가져오기
      </button>
    </div>
  );

onClick 이벤트 핸들러 등록 에러

 

기존에 진행하던 프로젝트에서는 마주한적 없던 에러인데 뭐가 문제일까요🤔

 

곰곰이 생각해 보니 다른 점은 라우팅 방식뿐이네요. 기존에는 Page Router 방식을 사용했지만 이번 프로젝트는 App Router 방식을 사용했습니다.

 

App Router 방식이 등장하면서 getStaticProps, getServerSideProps 같은 메소드가 사라지고,  fetch로 통합이 되었다고 합니다😱

Page Router 방식

 

App Router 방식

 

App Router 방식에서는 CSR(Client Side Rendering)을 어떻게 해야 할까요🤔

Next.js 공식 페이지의 ai에게 물어본 결과 아래처럼 응답해 줬습니다.

Next.js 공식 페이지 ai의 답변

 

간략하게 요약해 볼게요❗

use client란?

use client 디렉티브는 Next.js 애플리케이션에서 어떤 컴포넌트가 클라이언트 사이드에서 렌더링 되어야 하는지 명시적으로 정의하는 데 사용됩니다. use client를 파일에 추가하면, 해당 파일에서 import하는 모든 컴포넌트가 클라이언트 번들에 포함됩니다. 따라서 모든 컴포넌트에 use client를 추가할 필요는 없습니다.

 

언제 use client를 사용해야 하나요?

다음과 같은 경우에 use client를 사용해야 합니다:

  1. 인터랙티브 컴포넌트
    • useState, useEffect와 같은 React 훅을 사용해야 할 때
    • 클라이언트 사이드에서 상호작용이 필요한 컴포넌트
  2. 브라우저 전용 API
    • localStorage, window 객체, geolocation 등 브라우저에서만 사용할 수 있는 API를 접근해야 할 때
    • 이벤트 리스너 등을 사용할 때
  3. 서드파티 라이브러리
    • 브라우저 API나 DOM 조작에 의존하는 라이브러리를 사용할 때
    • 예를 들어, react-dom과 같은 라이브러리를 사용하는 컴포넌트

언제 use client를 사용하지 말아야 하나요?

  1. 정적 콘텐츠
    • 오직 정적 콘텐츠만 렌더링하는 컴포넌트
    • 서버에서 완전히 렌더링 할 수 있는 컴포넌트
  2. 데이터 페칭
    • 서버 컴포넌트에서 서버 사이드 데이터를 페칭하는 것을 선호
    • 서버 작업은 서버 액션 또는 API 라우트를 통해 수행

결론적으로 저는 클라이언트 사이드에서 버튼을 눌렀을 때 데이터를 비동기적으로 요청해야 하니까 CSR을 위해 use client를 추가해 보겠습니다.

"use client";

import db from "@/firebase/firestore";
import { doc, getDoc } from "firebase/firestore";

export default function Home() {
  const handleClick = async () => {
    const query = await getDoc(doc(db, "사용자", "zSen5y9LJazULo2C3atN"));
    console.log(query);
  };

  return (
    <div>
      <button
        className='bg-black text-white p-2 rounded-md'
        onClick={handleClick}
      >
        데이터 가져오기
      </button>
    </div>
  );
}

use client 추가 후 에러 해결

 

use client를 추가해 주니 에러 없이 잘 동작하네요👍

 

이번 에러를 통해 Next의 공식 문서도 정독해 보고 Next에 대한 많은 내용을 검색해보게 되었습니다. 

App Router가 도입되면서부터는 서버 컴포넌트에서 클라이언트 이벤트 핸들러를 사용할 수 없다는 것을 알게 되었습니다.

Next.js는 지속적으로 발전하고 있기 때문에, 이런 기능이나 제약이 바뀔 가능성도 충분히 있을 것 같습니다🤔

그래서 앞으로는 Next.js의 업데이트를 계속 따라가며, 최신 변화와 새로운 기능들을 놓치지 않기 위해 공식 문서를 주기적으로 확인할 계획입니다❗