Next.js Discord

Discord Forum

useEffect to invoke server action in client component

Answered
Cornish Rex posted this in #help-forum
Open in Discord
Cornish RexOP
I want to implement infinite scroll to load more content when user reaches the end of page. For the fetching I used a server action and according to [nextjs docs](https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations#useeffect) you can invoke them in useEffect, but when I run the app I'm getting this error:

Error: async/await is not yet supported in Client Components, only Server Components. This error is often caused by accidentally adding 'use client' to a module that was originally written for the server.

my code:
"use client"

import PostThumbnail from "@/components/PostThumbnail";
import getPosts from "@/components/ServerActions/getPosts";

import { useEffect, useState } from "react";
import { useInView } from "react-intersection-observer";

const NUMBER_OF_POSTS_TO_FETCH = 3

export default function PostsList({ initialPosts }) {

    const [posts, setPosts] = useState(initialPosts);
    const [offset, setOffset] = useState(NUMBER_OF_POSTS_TO_FETCH);
    const { ref, inView } = useInView();

    useEffect(() => {
        if (inView) {
            const fetchPosts = async () => {
                const newPosts = await getPosts(offset, NUMBER_OF_POSTS_TO_FETCH);
                setPosts([...posts, ...newPosts]);
                setOffset(offset + NUMBER_OF_POSTS_TO_FETCH);
            };
            fetchPosts();
        }
    }, [inView]);

    return (
        <div className="flex flex-col gap-5">
            {posts.map(post => <PostThumbnail post={post} key={post.id}/>)}
            <div ref={ref}>
                Loading...
            </div>
        </div>
    );
}
Answered by Cornish Rex
Ok... I just figured out what was the problem. I forgot to delete async from the function declaration in PostThumbnal 💀
View full answer

5 Replies

Can you show the post thumbnail component @Cornish Rex
@Arinji Can you show the post thumbnail component <@386619271767392262>
Cornish RexOP
import Image from 'next/image';
import Link from 'next/link';

export default async function PostThumbnail({ post } : { post: {
    author: {
        userName: string | null;
        image: string | null;
        name: string | null;
    };
  } & {
    id: string;
    title: string;
    content: string;
    imageUrl: string;
    authorId: string;
    createdAt: Date;
  } }) {

  const user = post.author;
  
  return (
    <div className='flex flex-col gap-5'>
      <div className='flex gap-3 p-3 rounded-md transition-colors duration-500 ease-in-out hover:bg-slate-50'>
        <div className="w-12 h-12 flex-shrink-0">
          <Link href={`/u/${user?.userName}`}>
            <Image src={user?.image as string} alt="" width={48} height={48} className="rounded-full"/>
          </Link>
        </div>
        <div className="flex flex-col gap-3 flex-grow">
          <div className='flex items-center justify-between'>
            <Link href={`/u/${user?.userName}`} className='font-bold hover:underline'>{user?.name}</Link>
            <p className='text-sm'>{`${post.createdAt.toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit', hour12: false })} ${post.createdAt.toLocaleDateString(undefined, { year: 'numeric', month: 'long', day: 'numeric' })}`}</p>
          </div>
          <Link href={`/p/${post.id}`} key={post.id}>
            <h1 className="text-2xl font-bold">{post.title}</h1>
            <img alt="" src={post.imageUrl} className="rounded-md bg-white object-contain border border-gray-400 w-full h-full max-h-96 object-cover"/>
          </Link>
        </div>
      </div>
      <div className="border-t border-gray-400 my-5"></div>
    </div>
  );
}
Cornish RexOP
Ok... I just figured out what was the problem. I forgot to delete async from the function declaration in PostThumbnal 💀
Answer
Cornish RexOP
@Arinji thanks 😄
Np