skip to Main Content

Raking my brain. Can’t seem to figure out why I’m getting the warning. I can comment out everything in both the page and component and still receive it. I would imagine it’s something simple I am completely overlooking. Hoping one of the smarter people out there can kick me in the butt.

I pulled pretty much all of my code to thin things out. Have a prisma query in LatestSites. If I take out the query and async the error goes away.

page.tsx

import { Container } from '@mui/material';
import LatestSites from './_components/LatestSites';

// export const dynamic = 'force-dynamic';

export default function Home() {
  return (
    <Container sx={{ pt: 2 }}>
      <LatestSites />
    </Container>
  );
}

LatestSites.tsx

import prisma from '@/prisma/client';

const LatestSites = async () => {
  const sites = await prisma.site.findMany({
    orderBy: { startDate: 'desc' },
    take: 5,
    include: {
      assignedToUser: true,
    },
  });

  return <div>test</div>;
};

export default LatestSites;

3

Answers


  1. Async functions in JavaScript always return Promise objects, which are not valid React children.

    Async calls should go inside useEffect in React:

    import { useEffect, useState } from 'react';
    import prisma from '@/prisma/client';
    
    const LatestSites = () => {
      const [sites, setSites] = useState();
      useEffect(() => {
        async function fetchSites() {
          const fetchedSites = await prisma.site.findMany({
            orderBy: { startDate: 'desc' },
            take: 5,
            include: {
              assignedToUser: true,
            },
          });
          setSites(fetchedSites);
        }
        fetchSites();
      }, []);
    
      return <div>test</div>;
    };
    
    export default LatestSites;
    
    Login or Signup to reply.
  2. Ross Allen makes a very good point and provides a good example that would work for something like create-react-app, however since this is tagged as Next.JS we can use some nice tooling provided.


    In Next.JS 13+ (when using the app router) we can use the use function provided by React to call asynchronous code:

    import { use } from "react";
    import prisma from '@/prisma/client';
    
    async function getSites() {
      return await prisma.site.findMany({
        orderBy: { startDate: 'desc' },
        take: 5,
        include: {
          assignedToUser: true,
        },
      })
    }
    
    export default function Home() {
      const sites = use(getSites());
      return <div>test</div>;
    }
    

    In Next.JS 9.3 – 12 (or 13+ using the pages router) we can use the getServerSideProps function provided by Next.JS to call asynchronous code on the server side:

    import { use } from "react";
    import prisma from '@/prisma/client';
    
    export async function getServerSideProps() {
      const sites = await prisma.site.findMany({
        orderBy: { startDate: 'desc' },
        take: 5,
        include: {
          assignedToUser: true,
        },
      });
    
      return {
        props: {
          sites: sites,
        }, // will be passed to the page component as props
      };
    }
    
    export default function Home({ sites }) {
        return <div>test</div>;
    }
    
    Login or Signup to reply.
  3. I tried reproducing your issue and I don’t get that error. Your LatestSites component is a valid react server component and you are totally allowed to make it an async function and make a call to prisma in it which blocks the rendering of the component till the prisma query resolves.
    Does wrapping LatestSites in a Suspense solve your issue?

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search