skip to Main Content

I created a small form(label, input with button ) to ensure that the loading indicator should show when submitting the form. I used @chakra-ui/react and react-hook-form to work on it. I want to show a "loading indicator for 2 sec at the time of submitting a form" as expected.

So far, I tried this to achieve my goal, but don’t know what I’m mistaking here.

Here is the live codesandbox example.

Please help me!

PS: I commented on the above example to get clarification on my issues.

2

Answers


  1. import "./styles.css";
    
    import { useForm } from "react-hook-form";
    import React, { useCallback, useState, useEffect } from "react";
    import {
      FormErrorMessage,
      FormLabel,
      FormControl,
      Input,
      Button
    } from "@chakra-ui/react";
    
    export default function App() {
      const [isSubmitting, setSubmitting] = useState(false);
    
      const onFinish = (event) => {
        event.preventDefault()
        setSubmitting(true);
    
        setTimeout(() => {
          setSubmitting(false);
        }, 2000)
      };
    
    
       const {
        register,
        formState: { errors }
      } = useForm();
    
      return (
        <form onSubmit={onFinish}>
          <FormControl isInvalid={errors.name}>
            <FormLabel htmlFor="name">First name</FormLabel>
            <Input
              id="name"
              placeholder="name"
              {...register("name", {
                required: "This is required",
                minLength: { value: 4, message: "Minimum length should be 4" }
              })}
            />
            <FormErrorMessage>
              {errors.name && errors.name.message}
            </FormErrorMessage>
          </FormControl>
          <Button mt={4} colorScheme="teal" isLoading={isSubmitting} type="submit">
            Submit
          </Button>
        </form>
      );
    }

    What you are doing, is after the form loads, the useEffect is being called after 2 seconds and setting the loading state to true. Then nothing else changes that loading state, and thus, keeps continuing to show the spinner. You need another event to stop the loading state and complete the submit. 🙂
    Next, just add inside the onFinish function what values you want to capture from the form 🙂

    In reality, you would want to set loading with the send of a promise, and set loading to false after the promise resolves. But I just added the code for demonstration.

    Login or Signup to reply.
  2. You dont need to create a seprate state to handle loading state of form when you are using react-hook-form

    You can just use its own loading state like this

     const {
            handleSubmit,
            control,
            setValue,
            // reset: resetForm,
            getValues: getFormValues,
            formState: { errors, isSubmitting },
       } = useForm()
    

    Also you can use react-hook-form handleSubmit to submit form like this

    <Button 
       mt={4} 
       colorScheme="teal" 
       isLoading={isSubmitting} 
       type="submit" 
       onSubmit={handleSubmit(onFinish)}
    >
        Submit
    </Button>
    

    By using it like this you will need to reshape your onFinish function like this and its shorter than your version of code

    const onFinish = (values) => {
       console.log(values) //your form values
    };
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search