最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Err Only plain objects, and a few built-ins, can be passed to Client Components from Server Components. Classes or

programmeradmin3浏览0评论

I fetch JSON file from external API using React Query. Below is fetch hook.

import { QueryClient, QueryKey, useQuery } from "@tanstack/react-query";
let Tmdb: string;

if (typeof process.env.NEXT_PUBLIC_TMDBURL === "string") {
  Tmdb = process.env.NEXT_PUBLIC_TMDBURL;
} else {
  throw new Error("NEXT_PUBLIC_TMDBURL is not defined");
}

export const useFetchData = () => {
  const queryClient = new QueryClient();

  const queryKey: QueryKey = ["repoData"];

  const { isLoading, error, data } = useQuery({
    queryKey,
    queryFn: async () => {
      const response = await fetch(Tmdb, { method: "GET" });
      const data = await response.json();
      if (!response.ok) {
        throw new Error("Network response was not ok");
      }

      if (isLoading) {
        console.log("ローディング中です");
      }
      if (error) {
        console.log("エラーです");
      }

      console.log(data);
      return data;
    },
  });

  return { data, isLoading, error };
};

And below one is the Component which use "useFetchData" hook.

import { QueryClient } from "@tanstack/react-query";
import { useFetchData } from "../hooks/useFetchData";

function PublishedMovieList() {
  const queryClient = new QueryClient();
  const { data, isLoading, error } = useFetchData();
  // 取得した"data"のタイプを定義する
  type FetchData = {
    adult: boolean;
    backdrop_path: string;
    belongs_to_collection: null;
    budget: number;
    genres: { id: number; name: string }[];
    homepage: string;
    id: number;
    imdb_id: string;
    original_language: string;
    original_title: string;
    overview: string;
    popularity: number;
    poster_path: string;
    production_panies: {
      id: number;
      logo_path: string;
      name: string;
      origin_country: string;
    }[];
    production_countries: { iso_3166_1: string; name: string }[];
    release_date: Date;
    revenue: number;
    runtime: number;
    spoken_languages: {
      english_name: string;
      iso_639_1: string;
      name: string;
    }[];
    status: string;
    tagline: string;
    title: string;
    video: boolean;
    vote_average: number;
    vote_count: number;
  };

  // 取得したdataを配列にする
  const movieList = (Object.keys(data) as (keyof FetchData)[]).map((keys) => {
    return { keys: keys[data] };
  });

  console.log(movieList);
  return (
    <div>
      <div>
        <p className="text-3xl py-5 pl-5">公開中作品</p>
      </div>
      <div className="flex space-x-10 pl-5">
        {movieList.map((item) => (
          <section className="w-1/5" key={item.id}>
            <img
              src={`/${item.poster_path}`}
            ></img>
          </section>
        ))}
      </div>
    </div>
  );
}

export default PublishedMovieList;

And below one is "page.tsx" file.

import PublishedMovieList from "./ponents/PublishedMovieList";
import Sidebar from "./ponents/Sidebar";
import {
  QueryClient,
  QueryClientProvider,
  useQuery,
} from "@tanstack/react-query";

const queryClient = new QueryClient();

export default function Home() {
  return (
    <QueryClientProvider client={queryClient}>
      <main className="bg-indigo-950 min-h-screen min-w-full">
        <div className="text-5xl py-10 pl-5 border-b border-white">
          <h1>今日、何観る?</h1>
        </div>

        <div className="flex">
          <div>
            <Sidebar />
          </div>
          <div>
            <PublishedMovieList />
          </div>
        </div>
      </main>
    </QueryClientProvider>
  );
}

When I start dev environment,"Only plain objects, and a few built-ins, can be passed to Client Components from Server Components. Classes or null prototypes are not supported." displayed.

I use below languages. ・React ver18 ・Next.js ver14.1.0 ・TypeScript ver5

I'm beginner for coding.If you are hard to read code, I apologize.

I mented out the "useFetchData" file because I think there is cause in fetch process. But it doesn't improve anything...

Please help me.

I fetch JSON file from external API using React Query. Below is fetch hook.

import { QueryClient, QueryKey, useQuery } from "@tanstack/react-query";
let Tmdb: string;

if (typeof process.env.NEXT_PUBLIC_TMDBURL === "string") {
  Tmdb = process.env.NEXT_PUBLIC_TMDBURL;
} else {
  throw new Error("NEXT_PUBLIC_TMDBURL is not defined");
}

export const useFetchData = () => {
  const queryClient = new QueryClient();

  const queryKey: QueryKey = ["repoData"];

  const { isLoading, error, data } = useQuery({
    queryKey,
    queryFn: async () => {
      const response = await fetch(Tmdb, { method: "GET" });
      const data = await response.json();
      if (!response.ok) {
        throw new Error("Network response was not ok");
      }

      if (isLoading) {
        console.log("ローディング中です");
      }
      if (error) {
        console.log("エラーです");
      }

      console.log(data);
      return data;
    },
  });

  return { data, isLoading, error };
};

And below one is the Component which use "useFetchData" hook.

import { QueryClient } from "@tanstack/react-query";
import { useFetchData } from "../hooks/useFetchData";

function PublishedMovieList() {
  const queryClient = new QueryClient();
  const { data, isLoading, error } = useFetchData();
  // 取得した"data"のタイプを定義する
  type FetchData = {
    adult: boolean;
    backdrop_path: string;
    belongs_to_collection: null;
    budget: number;
    genres: { id: number; name: string }[];
    homepage: string;
    id: number;
    imdb_id: string;
    original_language: string;
    original_title: string;
    overview: string;
    popularity: number;
    poster_path: string;
    production_panies: {
      id: number;
      logo_path: string;
      name: string;
      origin_country: string;
    }[];
    production_countries: { iso_3166_1: string; name: string }[];
    release_date: Date;
    revenue: number;
    runtime: number;
    spoken_languages: {
      english_name: string;
      iso_639_1: string;
      name: string;
    }[];
    status: string;
    tagline: string;
    title: string;
    video: boolean;
    vote_average: number;
    vote_count: number;
  };

  // 取得したdataを配列にする
  const movieList = (Object.keys(data) as (keyof FetchData)[]).map((keys) => {
    return { keys: keys[data] };
  });

  console.log(movieList);
  return (
    <div>
      <div>
        <p className="text-3xl py-5 pl-5">公開中作品</p>
      </div>
      <div className="flex space-x-10 pl-5">
        {movieList.map((item) => (
          <section className="w-1/5" key={item.id}>
            <img
              src={`https://image.tmdb/t/p/w185/${item.poster_path}`}
            ></img>
          </section>
        ))}
      </div>
    </div>
  );
}

export default PublishedMovieList;

And below one is "page.tsx" file.

import PublishedMovieList from "./ponents/PublishedMovieList";
import Sidebar from "./ponents/Sidebar";
import {
  QueryClient,
  QueryClientProvider,
  useQuery,
} from "@tanstack/react-query";

const queryClient = new QueryClient();

export default function Home() {
  return (
    <QueryClientProvider client={queryClient}>
      <main className="bg-indigo-950 min-h-screen min-w-full">
        <div className="text-5xl py-10 pl-5 border-b border-white">
          <h1>今日、何観る?</h1>
        </div>

        <div className="flex">
          <div>
            <Sidebar />
          </div>
          <div>
            <PublishedMovieList />
          </div>
        </div>
      </main>
    </QueryClientProvider>
  );
}

When I start dev environment,"Only plain objects, and a few built-ins, can be passed to Client Components from Server Components. Classes or null prototypes are not supported." displayed.

I use below languages. ・React ver18 ・Next.js ver14.1.0 ・TypeScript ver5

I'm beginner for coding.If you are hard to read code, I apologize.

I mented out the "useFetchData" file because I think there is cause in fetch process. But it doesn't improve anything...

Please help me.

Share Improve this question edited Mar 7, 2024 at 8:04 Youssouf Oumar 46.6k16 gold badges103 silver badges105 bronze badges asked Mar 7, 2024 at 0:43 NatsNats 431 silver badge3 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 7

Within the app router, ponents are by default server ponents (Home), and a server ponent can only pass a JSON serializable prop to client ponents (QueryClientProvider).

Or that queryClient you are passing to QueryClientProvider from Home is a plex object that contains functions and all. This is your problem.

You can add "use client" at the top of Home to make it a client ponent or, move the QueryClientContextProvider in its own file, like so:

// QueryClientContextProvider.tsx

"use client";

import { ReactNode } from "react";
import { QueryClient, QueryClientProvider, useQuery } from "@tanstack/react-query";

const queryClient = new QueryClient();

export default function QueryClientContextProvider({ children }: { children: ReactNode }) {
  return <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>;
}
import QueryClientContextProvider from "@/ponents/QueryClientContextProvider";
import PublishedMovieList from "./ponents/PublishedMovieList";
import Sidebar from "./ponents/Sidebar";

export default function Home() {
  return (
    <QueryClientContextProvider>
      <main className="bg-indigo-950 min-h-screen min-w-full">
        <div className="text-5xl py-10 pl-5 border-b border-white">
          <h1>今日、何観る?</h1>
        </div>
        <div className="flex">
          <div>
            <Sidebar />
          </div>
          <div>
            <PublishedMovieList />
          </div>
        </div>
      </main>
    </QueryClientContextProvider>
  );
}

Since QueryClientProvider relies on useContext under the hood, we have to put 'use client' on top This is why it is important to have the initial setup of tanstack react query in a separate file before importing it in the root layout.

https://tanstack./query/latest/docs/framework/react/guides/advanced-ssr

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论