Next.js Discord

Discord Forum

Using async in Client

Answered
Tonkinese posted this in #help-forum
Open in Discord
TonkineseOP
Hey,

I would like to do this in use client.
I have another project where I can use async in "use client", but here i get
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.

Can you explain me what to do

export default function Home(p: any) {
  const router = useRouter();
  const [loading, setLoading] = useState(false);

  async function onSubmit(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    setLoading(true);

    try {
      const formData = new FormData(event.currentTarget);
      const amount = formData.get("amount");
      const formattedAmount = parseFloat(amount).toFixed(2);

      const response = await fetch("/api/payment/create", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          name: await formData.get("name"),
          amount: await formattedAmount,
          message: await formData.get("message"),
          currency: await formData.get("currency"),
          creator: p.params.creator,
        }),
      });

      const data = await response.json();
      router.push(data.url);
    } catch (e: any) {
      router.refresh();
    } finally {
      setLoading(false);
    }
  }
Answered by Japanese Bobtail
did you get it working?
View full answer

70 Replies

Japanese Bobtail
can you share the whole component rather, specifically where this onSubmit is being invoked
TonkineseOP
yes
Wrong one
sorry
@Japanese Bobtail can you share the whole component rather, specifically where this onSubmit is being invoked
TonkineseOP
btw the error is there only very short and after 2 seconds i get pushed to data.url
Japanese Bobtail
hey let me see
all looks good here, the error's probably originating elsewhere
you can't have async component in client, this component just has an async function which is fine
check your StreamerProfile if thats an async component
@Tonkinese
TonkineseOP
Okay friend
Yes it was, i am going to test it again
But my Plan was to load something there from the database
So what would i need to do then
Japanese Bobtail
you can share that component
you usually just put those api calls in useEffect hooks, reactQuery if that's your goto
TonkineseOP
Okay yeah that was that issue!

import React from "react";
import { db } from "@/lib/modules";

export async function StreamerProfile({
  creatorName,
}: {
  creatorName: string;
}) {
  const data = await db.creator.findUnique({
    where: {
      name: creatorName,
    },
  });
  return (
    <div className="flex items-center justify-center mb-6">
      <img
        src={data.pictureUrl}
        alt={creatorName}
        className="h-20 rounded-full mr-4 pointer-events-none"
      />
      <h3 className="text-2xl font-semibold">{creatorName}</h3>
    </div>
  );
}
Does I have to mark it as "use server" then?
Because i am loading it in a client component?
Japanese Bobtail
'use client';
import React, { useEffect, useState } from 'react';
import { db } from '@/lib/modules';

export async function StreamerProfile({
  creatorName,
}: {
  creatorName: string;
}) {
  const [data, setData] = useState<any>(null);
  useEffect(() => {
    (async () => {
      const res = await db.creator.findUnique({
        where: {
          name: creatorName,
        },
      });
      setData(res);
    })();
  }, [creatorName]);

  return (
    <div className="mb-6 flex items-center justify-center">
      <img
        src={data.pictureUrl}
        alt={creatorName}
        className="pointer-events-none mr-4 h-20 rounded-full"
      />
      <h3 className="text-2xl font-semibold">{creatorName}</h3>
    </div>
  );
}
you can try this
TonkineseOP
Hmm what could i do then?
An API Route for fetching the user profile and name and then setting it as an state?
Japanese Bobtail
i updated the code that i shared, you can use it now
TonkineseOP
But are you sure that you can use prisma on client site?
and how safe is that?
@Tonkinese An API Route for fetching the user profile and name and then setting it as an state?
Japanese Bobtail
you just tell the component to fetch the data "whenever" your creator changes (via useEffect hook) and store the data in a state which then becomes the source of truth for the view
@Tonkinese and how safe is that?
Japanese Bobtail
oops didn't notice it was a db call, you will have to make an api route to use here
you can do that in next simple enough though, shouldn't be an issue
TonkineseOP
Okay so means basically if i work on clientside and need data it is everytime best practise to have an route where you fetch from, then useStates and useEffect for checking if that data changes?
Japanese Bobtail
yeah pretty much
TonkineseOP
Wow thats so nice. I am using nextjs a while but yesterday started doing much on clientside for a customer for example an api first dashboard where the frontend requests to the api live and now made my own project with payments where i request as client an donation link which the user gets redirected to and stuff like that.

Appreciate you so much
Japanese Bobtail
except useEffect will just refetch the data when creatorName changes, not when the response data changes ~
TonkineseOP
Because you setted it to creatorName, and with [] it would everything afaik, right?
TonkineseOP
Nice i already useEffect for example in the frontend project for checking every 5 seconds if the session is expired or active
Japanese Bobtail
it basically accepts a function and an array of dependencies..
whenever anything changes in your dependency, it will run the provided function
TonkineseOP
Or here for checking if the donation is already payed and showing a nice animation while it is processing
Japanese Bobtail
good one ^
TonkineseOP
I really like it and some time ago i thought aw man this stuff with client and server side is shit but it is very nice to work with actually.
And now i like it even more
Just having an api providing data for the client on button click if you wanna explain it in easy language for someone that never worked with next
Japanese Bobtail
are you using app router?
TonkineseOP
Yes I am using the app router
Btw do you know if there is socket.io support with nextjs or if there isnt any way of using it?
Japanese Bobtail
just like how you create pages, you can create api route by naming the file route.{js,jsx,ts,tsx}
within that, you will need to default export a function and that function will become the api route handler for you
TonkineseOP
Yeah okay from the backend / api site of nextjs i am familiar 🙂
My biggest problems were the stuff with what doing on the client side and what on server site
Japanese Bobtail
oh, in that case you will just have to create an api route and make a fetch call to it in place of db call, that's it
TonkineseOP
Bro I am so happy right now
@Tonkinese Btw do you know if there is socket.io support with nextjs or if there isnt any way of using it?
Japanese Bobtail
socket.io is supported wherever node is typically
~ yea it is supported
@Tonkinese Bro I am so happy right now
Japanese Bobtail
did you get it working?
Answer
TonkineseOP
Yes
I am currently on it
Japanese Bobtail
:all_the_things:
TonkineseOP
But I guess so
Japanese Bobtail
oh coolio, have fun :next1:
TonkineseOP
I wish you a great evening, thanks so much
TonkineseOP
@Japanese Bobtail I made the code now like when the creator isnt found / when the !response.ok it sets my name in the state so that my donation page gets shown
Testing it right now
And if that doesnt work i show an Creator doesnt exist state
TonkineseOP
@Japanese Bobtail Haha can get it working 😂
  useEffect(() => {
    (async () => {
      try {
        const res = await fetch(`/api/creator/${p.params.creator}`);
        const data = await res.json();
        if (data) {
          setCreatorData(data);
        } else {
          const fallbackRes = await fetch(`/api/creator/ipexa`);
          const fallbackData = await fallbackRes.json();
          setCreatorData(fallbackData);
        }
      } catch (error) {
        const fallbackRes = await fetch(`/api/creator/ipexa`);
        const fallbackData = await fallbackRes.json();
        setCreatorData(fallbackData);
      }
    })();
  }, []);
Japanese Bobtail
Lfgggg :lolsob:
TonkineseOP
Ah I just have to set a Initial State
TonkineseOP
@Japanese Bobtail Loading Time 💀