skip to Main Content

hey guys I am creating a booking app with Next js 14, I have route called /search-result which shows all the events fetched from backend as a server component. I am rendering some card inside this page which is client component, and each cards have book now button which redirect the user to the /booking page after storing the clicked item data in the cookies.
code.

const BookingHandler =  (data:any)=>{
        setLoading(true)
    
    const bookingSessing = {
        from: parameters?.from,
        where: parameters?.where,
        travel_date: item?.travel_date,
        arrival_time: item?.arrival_time,
        departure_time: item?.departure_time,
        passengers: parameters?.passengers,
        shipper: data?.shipper,
        seatclass: data?.class,
        ship_id: data?.ship_id,
        class_id: data?.class_id,
        schedule_id: data?.schedule_id,
        price: data?.price,
        token: token,
    }

    let encryptBookingSession = encryptdata(JSON.stringify(bookingSessing))
    setCookie('bookingSession', encryptBookingSession);
    router.push(`/booking`, )
    
    setLoading(false)
    
}

and this is the button component with onClick function.

<Button size='sm' onClick={() => BookingHandler(_i)}>
       {Loading ? <Loader2 className="mr-2 h-4 w-4 animate-spin" /> : null}                                       
       Book
</Button> 

Now the problem is I am facing that, when the button gets click, it takes around 1 or 2 second to respond and than redirect the user to /booking page. and loading spinner does not also. when I make the status of Loading status to true it does loading spinner but with onclick event its not showing.

The code I share is the client component inside the /search-result page.
here is the full page code.

    import Header from '@/components/Header'
import SearchForm from '@/components/SearchForm'
import FerryCards from '@/components/cards/FerryCards'
import { fetchFerry } from '@/lib/network-request/fetchFerry'
import React from 'react'



type SearchParam = {
  from: string,
  where: string,
  departure: string,
  passengers: string,

}


type SearchParamPops = {
  searchParams: SearchParam
}

type FerryData = {
  travel_date: string;
  departure_time: string;
  arrival_time: string;
  options: object;
};



const page = async ({ searchParams }: SearchParamPops) => {
  const parameters = {
    from: searchParams.from,
    where: searchParams.where,
    departure: searchParams.departure,
    passengers: searchParams.passengers

  }
  const response: any = await fetchFerry(parameters.from, parameters.where, parameters.departure, parameters.passengers)


  response?.data?.sort((a: FerryData, b: FerryData) => {
    return parseInt(a?.departure_time?.replace(":", "")) - parseInt(b?.departure_time?.replace(":", ""));
  });


  return (
    <>
    <Header/>
    <section>
      <div className="mx-auto max-w-7xl p-6 lg:px-8">
        <h1 className="text-4xl font-bold pb-3">Your Trip Results</h1>

        <h2 className="pb-3">
          Date of trip:
          <span className="italic ml-2">
            {parameters.departure}
          </span>
        </h2>
        <hr className="mb-5" />
        <h3 className="font-semibold text-xl">
          {response?.data?.length} results found
        </h3>
        <div className="space-y-2 mt-5">
          {response?.data?.map((item: any, index: number) => {
            return (
              <FerryCards key={index} item={item} parameters={parameters} token={response?.token} />
            )
          })}
        </div>
      </div>
    </section>
    </>
  )
}

export default page

the booking handler function which I have given above is inside the FerryCards component. what could be wrong I am doing here.

2

Answers


  1.         //src/app/page.tsx 
            import FerryCards from "./components/FerryCards";
    
            const fakaDat = [
              { id: 1, title: "test btn 1" },
              { id: 2, title: "test btn 2" },
              { id: 3, title: "test btn 3" },
              { id: 4, title: "test btn 4" },
            ];
    
            export default function Home() {
              return (
                <main className="flex min-h-screen flex-col items-center justify-between p-24">
                  {fakaDat.map((el) => (
                    <FerryCards key={el?.id} title={el?.title} />
                  ))}
                </main>
              );
            }
    
        //src/app/components/FerryCards.tsx
        "use client";
    
        import { useRouter } from "next/navigation";
        import { useState } from "react";
    
        export default function FerryCards({ title }: { title: string }) {
          const router = useRouter();
          const [loading, setLoading] = useState(false);
          const handleRedirect = () => {
            setLoading(true);
            router.push("/book");
          };
          return (
            <div className="flex flex-col items-center">
              <h1 className="text-3xl font-bold underline">Hello world!</h1>
              <button onClick={handleRedirect}>
                {loading ? "loading..." : "book"}
              </button>
            </div>
          );
        }
    

    I have prepared an example for you in this link

    Login or Signup to reply.
  2. Does your <Button/> component accept the onClick prop because you are using a component and not the built-in button tag, If it accepts onClick Prop, then

    Try this

    <Button
      size="sm"
      onClick={() => {
        setLoading(true);
        BookingHandler(_i);
      }}
    >
      {Loading ? <Loader2 className="mr-2 h-4 w-4 animate-spin" /> : null}
      Book
    </Button> 
    
    const BookingHandler =  (data:any)=>{
    
    // your all logic and then setLoading to false
    ...
    
    setLoading(curretnState =>  false)
    }
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search