Infinite scroll with data fetching from Supabase
Unanswered
European anchovy posted this in #help-forum
European anchovyOP
Is it possible to fetch data from supabase with a server component, so that the user doesn't have to wait so long for to receive that data? Could at least the first "page" of the infinite scroll come from a server component? I am trying to make a Twitter clone. Here is my infinite scroll component, but it's a client component. Any improvements or suggestions are welcome.
11 Replies
European anchovyOP
I managed to fetch the first page in a server component. Is there a way to do this for every fetch request ?
you can use server rendering with server actions: https://github.com/gabrielelpidio/next-infinite-scroll-server-actions
European anchovyOP
@riský thanks for your help I am checking it out now. I think this is better than my approach. I simply made a request to my db in a server component to get the first page and then inside of a client component I am doing all the other requests for the pages. I will try to understand this approach with the server actions and test it out. One new issue that I have now is that when I submit a new tweet it doesn't revalidate the path. I have created a server component to use a form server action to insert my new tweet into my database and there I revalidate the path. In a client component I am receiving that server action as a prop and I await it's response in a handle submit function for a form. If you could please provide some help to figure out why it doesn't revalidate the path when I submit a new tweet, I'd really appreciate it. Thank you in advance.
const ComposeTweetServer = async ({ user }: any) => {
const submitTweet = async (formData: FormData) => {
"use server";
const tweetText = formData.get("tweetText"); // textArea name
if (!tweetText) return;
const supabase = createServerActionClient({ cookies });
// try {
// TODO: validate insert - tweet content
const { data, error } = await supabase.from("tweets").insert({
user_id: user.id,
text: tweetText.toString(),
});
if (error) {
console.log(error);
}
// } catch (error) {
// console.log(error);
// }
revalidatePath("/home");
return { data, error };
};
return <ComposeTweetClient user={user} serverAction={submitTweet} />;
};
export default ComposeTweetServer;and from the client component:
const postTweet = async (data: FormData) => {
if (
tweetTextRef.current &&
tweetTextRef.current.value !== "" &&
tweetTextRef.current.value.length <= tweetMaxLength
) {
try {
const response = await serverAction(data);
console.log(response);
tweetTextRef.current.value = "";
if (response?.error) {
console.log(response.error.message);
}
} catch (error) {
console.log(error);
}
}
};
return (
<>
<form
action={postTweet}
className="flex flex-col w-full flex-grow px-2 pt-2"
>
<div className="flex flex-col w-full">
<div className="flex flex-col border-b">
<textarea
ref={tweetTextRef}
onChange={handleChange}
maxLength={characterLimit}
name="tweetText"
// add invisible scrollbar
className="bg-transparent border-none outline-none resize-none pt-2"
placeholder="What is happening?!"
/>
</div>
<div className="flex flex-col items-end mt-4">
<div className="flex">
{remainingChars <= 20 && (
<p className={`py-2 px-4 text-${remainingCharsColor}`}>
{remainingChars}
</p>
)}
<button
type="submit"
className="rounded-full bg-blue-500 py-2 px-4"
// onClick={postTweet}
>
Post
</button>
</div>
</div>
</div>
</form>there is a quick flickering or something so it might actually revalidate the /home path...but nothing happens....idk why
const { data, error } = await supabase
.from("tweets")
.select("*, author: profiles(*), likes(*)")
.order("created_at", { ascending: false })
.limit(10);
const tweets = data?.map((tweet: any) => ({
...tweet,
user_has_liked: !!tweet.likes.find(
(like: any) => like.user_id === user?.id
),
likes: tweet.likes.length,
}));
return (
<>
<MainHeader />
<ComposeTweetServer user={user} />
<InfiniteFeed user={user} firstTweetsPage={tweets} />
</>
); this is the home path page.tsxEuropean anchovyOP
if I remove the infiniteFeed, which is where I fetch my tweets with the scroll... then I can make a new post and the revalidatePath to /home works and it shows the new post on top...but this only works if I fetch all the tweets at once instead of only the first 10 in the server component and the others with the scroll in the InfiniteFeed....why ?
European anchovyOP
I've fixed it. It was a react issue. My bad.
@European anchovy I've fixed it. It was a react issue. My bad.
wait, so using server actions worked? if so YAY!
European anchovyOP
@riský oh no I didn't implement it that way yet. I will try it soon and let you know if it works. For now I am fetching the first page in a server component, the rest of the pages are fetched in a client component and stored there in a react usestate. I have a server component to submit a new tweet and a client component for that as well. The issue was that I revalidate the path in that server submit tweet component and I then have to reset the initial state of my useState which contains the second tweet page and the rest. I fixed that now so it all works as expected and I will try to do it with server actions now because I hope it will be faster and revalidating the path makes some components flicker for a split second idk why.