Home > front end >  Error: Objects are not valid as a React child in the app directory of Next.js
Error: Objects are not valid as a React child in the app directory of Next.js

Time:01-03

I started migrating one of my Next.js applications to version 13. I wanted to use the app directory with Server and Client Components. The documentation says that:

Server and Client Components can be interleaved in the same component tree. Behind the scenes, React will merge the work of both environments.

But my below attempt fails with this error:

Error: Objects are not valid as a React child (found: [object Promise]). If you meant to render a collection of children, use an array instead.

"use client";

import Comments from "./Comments";

const Post = () => {
  return (
    <div>
      <p>This is a post</p>
      <Comments />
    </div>
  );
};

export default Post;
export default async function Comments() {
  const res = await fetch("https://jsonplaceholder.typicode.com/comments");
  return <div></div>;
}

I have looked around the Internet and Stack Overflow but didn't find an answer. Any help would be appreciated.

CodePudding user response:

If you continued a little bit through the documentation, you would have seen that they talk about a restriction when it comes to Render, a Server Component inside a Client Component:

However, in React, there's a restriction around importing Server Components inside Client Components because Server Components might have server-only code (e.g. database or filesystem utilities).

For example, importing a Server Component in a Client Component will not work:

'use client';

// ❌ This pattern will not work. You cannot import a Server
// Component into a Client Component
import ServerComponent from './ServerComponent';

export default function ClientComponent() {
  return (
    <>
      <ServerComponent />
    </>
  );
}

Instead, you can pass a Server Component as a child or prop of a Client Component. You can do this by wrapping both components in another Server Component. For example:

'use client';

export default function ClientComponent({children}) {
  return (
    <>
      {children}
    </>
  );
}
// ✅ This pattern works. You can pass a Server Component
// as a child or prop of a Client Component.
import ClientComponent from "./ClientComponent";
import ServerComponent from "./ServerComponent";

// Pages are Server Components by default
export default function Page() {
  return (
    <ClientComponent>
      <ServerComponent />
    </ClientComponent>
  );
}

Following these guidelines, in your case, you should pass Comments as children to Post, like so:

"use client";

const Post = ({ children }) => {
  return (
    <div>
      <p>This is a post</p>
      {children}
    </div>
  );
};

export default Post;
<Post>
  <Comments/>
</Post>
  • Related