Err 只有普通对象和一些内置对象可以从服务器组件传递到客户端组件。不支持类或空原型

问题描述 投票:0回答:1

我使用 React Query 从外部 API 获取 Json 文件。 下面是获取钩子。

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 };
};

下面是使用“useFetchData”钩子的组件。

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_companies: {
      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.org/t/p/w185/${item.poster_path}`}
            ></img>
          </section>
        ))}
      </div>
    </div>
  );
}

export default PublishedMovieList;

下面是“page.tsx”文件。

import PublishedMovieList from "./components/PublishedMovieList";
import Sidebar from "./components/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>
  );
}

当我启动开发环境时,“只有普通对象和一些内置对象可以从服务器组件传递到客户端组件。不支持类或空原型。”显示。

我使用以下语言。 ・反应版本18 ・Next.js 版本14.1.0 ・TypeScript ver5

我是编码初学者。如果您很难阅读代码,我深表歉意。

我注释掉了“useFetchData”文件,因为我认为在获取过程中存在原因。 但这并没有改善任何事情...

请帮助我。

typescript next.js react-hooks
1个回答
0
投票

app
路由器中,组件默认是服务器组件(
Home
),并且服务器组件只能将 JSON 可序列化属性传递给客户端组件(
QueryClientProvider
)。

或者您从

queryClient
传递到
QueryClientProvider
Home
是一个包含函数等的复杂对象。这是你的问题。

您可以在

"use client"
顶部添加
Home
使其成为客户端组件,或者将
QueryClientContextProvider
移动到其自己的文件中,如下所示:

// 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 "@/components/QueryClientContextProvider";
import PublishedMovieList from "./components/PublishedMovieList";
import Sidebar from "./components/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>
  );
}
© www.soinside.com 2019 - 2024. All rights reserved.