Use Client 관련 트러블 슈팅

채영민·2024년 2월 16일

📚 'Use Client' 트러블 슈팅 (2024년 2월 16일)

  • 서버 컴포넌트에서 Use Client를 사용했는데, 에러가 발생했다.
// components/movie-video.tsx
"use client";

import styles from "../styles/movie-videos.module.css";
import { API_URL } from "../app/(home)/page";

async function getVideos(id: string) {
	const response = await fetch(${API_URL}/${id}/videos);
	return response.json();
}

export default async function MovieVideos({ id }: { id: string }) {
	const videos = await getVideos(id);

	return (
		<div className={styles.container}>
		{videos.map((video) => (
			<iframe
				key={video.id}
				src={https://youtube.com/embed/${video.key}}
				title={video.name}
				/>
		))}
		</div>
	);
}

에러 : Error: × You are attempting to export "metadata" from a component marked with "use client", which is disallowed. Either remove the export, or the "use client" directive.

(에러 메세지 전문)	Error: × You are attempting to export "metadata" from a component marked with "use client", which is disallowed. Either remove the export, or the "use client" directive. Read more: https://nextjs.org/ │ docs/getting-started/react-essentials#the-use-client-directive │ │ ╭─[/Users/chaeyeongmin/Desktop/JavaScript/Next.js/nextjs14/app/(home)/page.tsx:2:1] 2 │ import Movie from "../../components/movie"; 3 │ import styles from "../../styles/home.module.css"; 4 │ 5 │ export const metadata: Metadata = { · ──────── 6 │ title: "Home", 7 │ }; ╰──── Import trace for requested module: ./app/(home)/page.tsx ./components/movie-videos.tsx    
  • 위 메세지에 따르면 다음 파일에서 에러가 발생했다고 한다.
import { Metadata } from "next";
import Movie from "../../components/movie";
import styles from "../../styles/home.module.css";

export const metadata: Metadata = {
  title: "Home",
};

export const API_URL = "https://nomad-movies.nomadcoders.workers.dev/movies";

async function getMovies() {
  const response = await fetch(API_URL);
  const json = await response.json();
  return json;
}

export default async function HomePage() {
  const movies = await getMovies();
  return (
    <div className={styles.container}>
      {movies.map((movie) => (
        <Movie
          key={movie.id}
          id={movie.id}
          poster_path={movie.poster_path}
          title={movie.title}
        />
      ))}
    </div>
  );
}
  • 🗣️ 에러 메시지를 읽어보니, 지속적으로 metadata를 export하는 행위를 지적하고 있어서 나는 metadata를 사용하는 것이 잘못된 줄 알았다. 그러나 위의 두 파일에서 metadata는 전혀 연관이 없었고, 결국 문제의 원인은 'use client' 지시어의 특성에 있었다. 'use client' 지시어가 붙은 컴포넌트에서는 어떠한 변수도 export할 수 없는 것이 원칙이기 때문에, 이를 위반했던 것이 문제였다. 이러한 원리를 이해하고 나니, API_URL을 각각의 컴포넌트에서 따로 선언함으로써 문제를 해결할 수 있었다.

  • 💡 오류 해결

  • 다음과 같이 import로 참조해오던 API_URL을 해당 파일안에서 불러주었다.
"use client";

import styles from "../styles/movie-videos.module.css";

async function getVideos(id: string) {
  const API_URL = "https://nomad-movies.nomadcoders.workers.dev/movies";
  const response = await fetch(`${API_URL}/${id}/videos`);
  return response.json();
}

export default async function MovieVideos({ id }: { id: string }) {
  const videos = await getVideos(id);

  return (
    <div className={styles.container}>
      {videos.map((video) => (
        <iframe
          key={video.id}
          src={`https://youtube.com/embed/${video.key}`}
          title={video.name}
</iframe>
      ))}
    </div>
  );
}
profile
항상 재밌는것을 찾아 헤매는 호랑이띠 떠돌이;

0개의 댓글