react-hook-form: isSubmitting does not update

Describe the bug I have an issue with formState.isSubmitting.

I am using controlled fields and a <Button> component from the react-native-elements library that accepts a loading propriety to automatically change the style of the <Button> with a loading spinner.

However, although the value of formState.isSubmitting seems to be set to true when calling handleSubmit (I have traced its value with console.log()) the <Button> style does not change during the form submission.

Codesandbox link (Required) I could not generate a sandbox for this issue but here is a snippet describing the issue:

import React from "react";
import { useForm, Controller } from "react-hook-form";
import { KeyboardAvoidingView, View } from "react-native";
import { Button, Input } from "react-native-elements";

export default () => {
  const { handleSubmit, errors, control, formState } = useForm();
  const onSubmit = (data)=> {
    console.log(formState );
  };

  return (
    <View
      style={{
        alignSelf: "center",
        height: "100%",
        width: "100%"
      }}
    >
      <View
        style={{
          flex: 2,
          justifyContent: "center"
        }}
      >
        <KeyboardAvoidingView style={{ marginBottom: 16 }}>
          <Controller
            as={Input}
            autoCapitalize="none"
            autoCompleteType="email"
            containerStyle={{ marginBottom: 12 }}
            control={control}
            errorMessage={errors.email && errors.email.message}
            keyboardType="email-address"
            name="email"
            placeholder="Email Address"
            rules={{
              pattern: {
                message: "The email address format is invalid.",
                value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i
              },
              required: {
                message: "This field is required.",
                value: true
              }
            }}
            onChange={args => args[0].nativeEvent.text}
          />
          <Button
            disabled={!formState.isValid}
            loading={formState.isSubmitting}
            title="RESET PASSWORD"
            type="solid"
            onPress={handleSubmit(onSubmit)}
          />
        </KeyboardAvoidingView>
      </View>
    </View>
  );
};

Expected behavior On form submission, the value of formState.isSubmitting should be set to true and the style for the <Button loading={formState.isSubmitting}> from react-native-elements should get updated with the spinner.

Smartphone (please complete the following information):

  • Device: Pixel 3
  • OS: Android R

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 18 (9 by maintainers)

Most upvoted comments

@aress31 are you sure return Promise from onSubmit function? Or maybe API request is too fast, and you didn’t notice the loading indicator? Try this snippet for a test.

const onSubmit = data => {
    return new Promise((resolve) => {
      setTimeout(() => resolve(), 1000);
    });
  };

@bluebill1049, @mixail-novikov and @JeromeDeLeon thanks for your help, indeed the API fetch was just way to fast to appear on the screen but with the timer example I could see that the code is working as it should.

Also, my onSubmit function did not return anything, that was the main issue I believe it was wrapped around curly brackets without a return statement, adding the return statement solved the issue.

// submit handler
const onSubmit = data => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve();
    }, 3000);
  });
}

// submit button
<Button
  disabled={formState.isSubmitting}
  onPress={handleSubmit(onSubmit)}
  title="RESET PASSWORD"
/>

const { handleSubmit, errors, control, formState: { isSubmitting } } = useForm();

https://react-hook-form.com/api#formState

I think you miss the Proxy part which is in the doc.

Closing this issue as i have provided both CSB and Expo snack examples. feel free to follow up with more questions.

@aress31 are you sure return Promise from onSubmit function? Or maybe API request is too fast, and you didn’t notice the loading indicator? Try this snippet for a test.

const onSubmit = data => {
    return new Promise((resolve) => {
      setTimeout(() => resolve(), 1000);
    });
  };

Chiming in, using the suggestion @mixail-novikov works and that you made a mistake by passing false to disabled prop instead of formState.isSubmitting

<Button
  disabled={false}
  onPress={handleSubmit(onSubmit)}
  title="RESET PASSWORD"
/>

I also tried the expo you provided @sgobotta and managed to get it worked with above solution.

not really with useEffect:

function Test() {
  const { handleSubmit, errors, control, formState: { isSubmitting } } = useForm();
  console.log('isSubmitting', isSubmitting);

  return {
    <form onSubmit={handleSubmit(() => {})}>
      {isSubmitting}

      <button>Submit</button>
    </form>
  }
}

@bluebill1049 thanks for your answer, indeed the documentation states that Proxy needs to get invoked or read before render to enable state update.

However, I am not sure how to use Proxy together with react hook form. Could you be kind enough to provide a working code snippet? And maybe adding it to the official documentation would help other people too.