#pending not working

1 messages · Page 1 of 1 (latest)

jagged ibex
#

Why is my pending varfialbe not working hnere?
none of hte laoidng states re showing

/* eslint-disable @next/next/no-img-element */
"use client";

import axios from "axios";
import { generateCoverArt } from "@/server/generate";
import { use, useEffect, useRef, useState } from "react";
import { useFormState, useFormStatus } from "react-dom";
import { Playlist } from "@/types/spotify";
import { Loader2 } from "lucide-react";

export default function Form() {
const submitRef = useRef<React.ElementRef<"button">>(null);
const [formState, formAction] = useFormState(generateCoverArt, null);
const imageGen = formState?.image;
const { pending } = useFormStatus();

return (
<form action={formAction}>
<div className="mt-2 flex h-12 mb-5">
<input
type="url"
name="spotify-url"
id="spotify-url"
onKeyDown={(e) => {
if (e.key === "Enter") {
e.preventDefault();
submitRef.current?.click();
}
}}
className="block w-full rounded-lg py-1.5 pl-2 text-white-900 border-2 outline-none border-green-500 shadow-sm ring-1 ring-inset placeholder:text-gray-400 focus:ring-2 ring-green-300 focus:ring-inset focus:ring-green-400 sm:text-sm sm:leading-6 bg-black"
placeholder="Spotify playlist link"
required
/>
<button
ref={submitRef}
disabled={pending}
aria-disabled={pending}
type="submit"
className="button w-40 bg-green-500 rounded-lg flex justify-center items-center ml-5"
>
{pending ? (
<Loader2
size={16}
className="animate-spin text-white font-bold text-lg"
/>
) : (
<span className="text-white font-bold text-lg">Generate</span>
)}
</button>
</div>
<div className="">
{imageGen ? (
<img
src={imageGen}
alt="Generated Art"
className="rounded-lg aspect-[1/1] w-full"
/>
) : (
pending && (
<div className="aspect-[1/1] w-full bg-green-500 rounded-lg flex flex-col items-center justify-center">
<div className="animate-spin rounded-full border-b-2 border-white h-16 w-16"></div>
<p className="mt-6">
This can take anywhere from 30 to 60 seconds to finish.
</p>
</div>
)
)}
</div>
</form>
);
}

steady juncoBOT
#

Hi @jagged ibex. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

The pending variable from useFormStatus() is used to show a loading state when a form is submitting on the server. According to the Next.js documentation (https://nextjs.org/docs/app/building-your-application/data-fetching/forms-and-mutations#displaying-loading-state), the useFormStatus hook can only be used as a child of a form element using a Server Action.

In your code, you are using useFormStatus() correctly as a child of a form element. However, there are a few things you might want to check:

  1. Make sure that the server action generateCoverArt is correctly set up and is returning a promise. The pending state is true when the promise is not yet resolved or rejected.

  2. Ensure that the useFormState() hook is correctly set up. The first argument should be the server action and the second argument should be the initial state.

  3. Check if the server action is correctly triggered when the form is submitted.

  4. Make sure that the version of Next.js you are using supports the experimental feature of useFormStatus(). According to the Github issue (https://github.com/vercel/next.js/issues/55919), this feature is available starting from version 13.5.

If you've checked all of these and the issue still persists, it might be a bug with Next.js or a specific issue with your project setup. You might want to consider creating an issue on the Next.js Github page or asking for help on the Next.js community forum.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@jagged ibex kapa.ai is still learning and improving, please let us know how it did by reacting below

jagged ibex
#

can you give me an example of using pending formStatus @steady junco

steady juncoBOT
#

Let me check the knowledge base for you. One moment! :books:

#

Sure, here's an example of using the pending variable from useFormStatus() in a Next.js application:

// Import the necessary hooks
import { useFormStatus } from 'react-dom'

export function SubmitButton() {
  // Use the useFormStatus hook to get the pending state
  const { pending } = useFormStatus()

  // Use the pending state to disable the button and change its text while the form is submitting
  return (
    <button type="submit" aria-disabled={pending}>
      {pending ? 'Loading...' : 'Submit'}
    </button>
  )
}

In this example, the SubmitButton component uses the useFormStatus hook to get the pending state. This state is then used to disable the button and change its text while the form is submitting.

You can then use this SubmitButton component in a form with a Server Action like so:

import { SubmitButton } from '@/app/submit-button'
 
export default async function Home() {
  return (
    <form action={...}>
      <input type="text" name="field-name" />
      <SubmitButton />
    </form>
  )
}

This example is based on the information provided in the Next.js documentation (https://nextjs.org/docs/app/building-your-application/data-fetching/forms-and-mutations#displaying-loading-state).

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@jagged ibex kapa.ai is still learning and improving, please let us know how it did by reacting below

jagged ibex
#

but what if i want to show a pending state in Home as well @steady junco

steady juncoBOT
#

Let me check the knowledge base for you. One moment! :books:

#

If you want to show a pending state in the Home component as well, you can use the useFormStatus hook in the Home component too. However, remember that useFormStatus can only be used as a child of a form element using a Server Action.

Here's an example:

import { SubmitButton } from '@/app/submit-button'
import { useFormStatus } from 'react-dom'
 
export default async function Home() {
  const { pending } = useFormStatus()

  return (
    <form action={{...}}>
      <input type="text" name="field-name" />
      <SubmitButton />
      {pending && <p>Loading...</p>}
    </form>
  )
}

In this example, while the form is submitting (i.e., the pending state is true), a loading message is displayed.

Please note that this is a simplified example and you might need to adjust it according to your specific use case and project setup. The information is based on the Next.js documentation (https://nextjs.org/docs/app/building-your-application/data-fetching/forms-and-mutations#displaying-loading-state) and the Github issue (https://github.com/vercel/next.js/issues/55919).

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@jagged ibex kapa.ai is still learning and improving, please let us know how it did by reacting below

jagged ibex
#

@steady junco this doenst work though, only the loading state of the button works

/* eslint-disable @next/next/no-img-element */
"use client";

import axios from "axios";
import { generateCoverArt } from "@/server/generate";
import { use, useEffect, useRef, useState } from "react";
import { GenerateButton } from "./generate-button";
import { useFormState, useFormStatus } from "react-dom";
import { Playlist } from "@/types/spotify";

export default function Form() {
const submitRef = useRef<React.ElementRef<"button">>(null);
const [formState, formAction] = useFormState(generateCoverArt, null);
const imageGen = formState?.image;
const { pending } = useFormStatus();

return (
<form action={formAction}>
<div className="mt-2 flex h-12 mb-5">
<input
type="url"
name="spotify-url"
id="spotify-url"
onKeyDown={(e) => {
if (e.key === "Enter") {
e.preventDefault();
submitRef.current?.click();
}
}}
className="block w-full rounded-lg py-1.5 pl-2 text-white-900 border-2 outline-none border-green-500 shadow-sm ring-1 ring-inset placeholder:text-gray-400 focus:ring-2 ring-green-300 focus:ring-inset focus:ring-green-400 sm:text-sm sm:leading-6 bg-black"
placeholder="Spotify playlist link"
required
/>
<GenerateButton ref={submitRef} />
</div>
<div className="">
{imageGen ? (
<img
src={imageGen}
alt="Generated Art"
className="rounded-lg aspect-[1/1] w-full"
/>
) : (
pending && (
<div className="aspect-[1/1] w-full bg-green-500 rounded-lg flex flex-col items-center justify-center">
<div className="animate-spin rounded-full border-b-2 border-white h-16 w-16"></div>
<p className="mt-6">
This can take anywhere from 30 to 60 seconds to finish.
</p>
</div>
)
)}
</div>
</form>
);
}

steady juncoBOT
#

Let me check the knowledge base for you. One moment! :books:

#

The pending state from useFormStatus() is used to show a loading state when a form is submitting on the server. However, it seems like the loading state is not showing up in your Home component as expected.

One possible reason could be that the generateCoverArt server action is not correctly set up or not returning a promise. The pending state is true when the promise is not yet resolved or rejected.

Here's a simplified example of how to use useFormStatus():

import { useFormStatus } from 'react-dom'

export default function Home() {
  const { pending } = useFormStatus()

  return (
    <form action={{...}}>
      {pending ? <p>Loading...</p> : <p>Not loading</p>}
    </form>
  )
}

In this example, a loading message is displayed while the form is submitting (i.e., the pending state is true).

Please note that this is a simplified example and you might need to adjust it according to your specific use case and project setup. The information is based on the Next.js documentation (https://nextjs.org/docs/app/building-your-application/data-fetching/forms-and-mutations#displaying-loading-state) and the Github issue (https://github.com/vercel/next.js/issues/55919).

If you've checked all of these and the issue still persists, it might be a bug with Next.js or a specific issue with your project setup. You might want to consider creating an issue on the Next.js Github page or asking for help on the Next.js community forum.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@jagged ibex kapa.ai is still learning and improving, please let us know how it did by reacting below

jagged ibex
#

@steady junco is there any toher way to check if it's loading?

steady juncoBOT
#

Let me check the knowledge base for you. One moment! :books:

#

Yes, there are other ways to manage loading states in your application. One common approach is to use React's useState hook to manually manage a loading state. Here's an example based on the code you provided:

import React, { useState } from 'react';

export default function Form() {
  const [isLoading, setIsLoading] = useState(false);

  const handleSubmit = async (event) => {
    event.preventDefault();
    setIsLoading(true);

    // Call your API here

    setIsLoading(false);
  };

  return (
    <form onSubmit={handleSubmit}>
      {/* Your form fields here */}
      {isLoading ? (
        <div>Loading...</div>
      ) : (
        <button type="submit">Submit</button>
      )}
    </form>
  );
}

In this example, we initialize a state variable isLoading with an initial value of false. When the form is submitted, we set isLoading to true, make the API call, and then set isLoading back to false once the API call is complete.

This approach gives you full control over when the loading state is shown and hidden, but it does require you to manually manage the state.

Please note that this is a simplified example and you might need to adjust it according to your specific use case and project setup. The information is based on the Next.js documentation (https://nextjs.org/docs/pages/building-your-application/data-fetching/forms-and-mutations#examples-displaying-loading-state).

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@jagged ibex kapa.ai is still learning and improving, please let us know how it did by reacting below

jagged ibex
#

@steady junco is there anyway i can use useFormStatus outside of the button though but still inside the form

steady juncoBOT
#

Let me check the knowledge base for you. One moment! :books: