When I am submiting the form submitSucceeded props goes true, pristine is also working fine but submitting props not change on submit form. I have attached related code. Please suggest me how I can fix this issue.
import React from 'react'
import { Field, reduxForm } from 'redux-form'
import FileInput from '../FileInput'
import 'react-widgets/dist/css/react-widgets.css';
import './reactForm.css';
const EditForm = (props) => {
const { handleSubmit, submitSucceeded, pristine, submitting, owners, cities, compound, avatarUrl, changeAvatar } = props;
return (
<form onSubmit={handleSubmit}>
<div className="row padding-20-0">
<div className="col-md-4">
<div className="box-upfile cursor" style={{backgroundImage: `url(${avatarUrl})`}} >
<div className="editImgComp" >
<i className="sprite-icon icon-030" onClick={()=>{changeAvatar(null); props.change('avatar', null)}}/>
<label html="imageBrowse">
<FileInput
onDone={(file)=> {changeAvatar(file.file); props.change("avatar", file.file)}}
type="file" className="hidden" id="imageBrowse"/>
<i className="sprite-icon icon-031"/>
</label>
</div>
</div>
</div>
</div>
<div className="row">
<div className="text-right col-xs-6">
{
submitSucceeded ?
<button type="button" className="btn ls-btn-red cursor" disabled={pristine || submitting || submitSucceeded}>
<i className='fa fa-circle-o-notch fa-spin'></i> Saving
</button>
:
<button type="submit" className="btn ls-btn-red cursor" disabled={pristine || submitting} onClick={handleSubmit} >Save</button>
}
</div>
</div>
</form>
)
}
export default reduxForm({
form: 'compoundForm' // a unique identifier for this form
})(EditForm)
Container:-
handleSubmit(data) {
this.props.dispatch(compoundSave(data));
}
Action:-
export function compoundSave(data) {
const id = data.id;
const config = {
method: 'put',
body: JSON.stringify({compound: data}),
};
return callApi('/v1/compounds/'+id, {}, config, compoundSaveRequest, compoundSaveSuccess, compoundSaveFailure);
}
Call Api method:-
`export function callApi(path, params, config, request, onRequestSuccess, onRequestFailure) {
const API_ROOT = 'http://api.dev.leasing.clicksandbox.com:8080';
const idToken = localStorage.getItem('id_token');
let url = API_ROOT+path;
url = buildUrlWithQueryString(url, params);
return dispatch => {
dispatch(request);
return fetch(url, config)
.then(checkStatus)
.then(parseJSON)
.then((json) => {
if (!json.success) { // (response.status < 200 || response.status > 300)
json.error &&
Toastr.error(json.error);
dispatch(onRequestFailure(json));
} else {
json.message &&
Toastr.success(json.message);
dispatch(onRequestSuccess(json));
}
}).catch((error) => {
const exceptionMessage = {
success: false,
error: "Something went wrong!"
}
dispatch(onRequestFailure(exceptionMessage));
});
};
}`
Please let me know if I need to explain more.
For any one else arriving here a year later like me looking for answers, and without seeing the Container code... i can infer that the problem is that you defined the method handleSubmit in the Container and send it as a prop to EditForm. The problem with that is that a Component that has the reduxForm() HOC applied, in this case EditForm, will generate its own handleSubmit prop, and therefore a conflict arises, leading to wrong behaviour of the form when submitting.
In order to fix the issue, you should have send the prop to EditForm with a different name say
<EditForm onSubmit={this.onSubmit} />
And then inside the EditForm component use it like:
...
<form onSubmit={handleSubmit(onSubmit)}>
That way the prop submitting of the reduxForm component will work if the submit handler returns a promise.
you should call handleSubmit() method with handler passed to component :
<form onSubmit={handleSubmit(this.props.onSubmit)}>
Related
I have a form created with redux-form.
I added a dropzone created with react-dropzone.
I have two endpoints:
[POST] /image: to upload an image (using react-dropzone). This returns a payload that contains the ID of the just uploaded file (saved in the database in the backend)
[POST] /my_entity: to save the entity I'm creating (using redux-form)
The uploading process is this:
When drop one or more files in the dropzone, then a callback from the main form is called;
The callback from the main form calls a thunk that uploads the file calling my upload endpoint ([POST] /image);
My upload endpoint returns a payload with the data of the just uploaded file and its assigned ID in the form of a resource URI (ex.: /images/1)
A redux managed by redux-orm saves the payload in Redux
WHAT I NEED TO ACHIEVE
I need to add the ID of the just uploaded file to a field managed by redux-form.
When clicking "Save" or "Update", I need to send to call [POST] /my_entity.
The payload I need to send is similar to this:
{
"title": "The custom title",
"newImages": [
"/images/1",
"/images/2",
"/images/3"
]
}
WHICH IS THE PROBLEM
My problem is that I'm not able to find a path to add the resource URI (ex.: image/1) to the field newImages managed by redux-form.
My code
The Form component
class Form extends React.Component {
constructor(props) {
super(props);
this.state = { uploadingImages: [] };
this.onDrop = this.onDrop.bind(this);
}
onDrop(acceptedFiles) {
const { onImageUpload } = this.props;
acceptedFiles.map((file) => {
const reader = new FileReader();
const thumbnailTmpId = cuid();
reader.onload = (e) => {
// Add the image into the state.
// Since FileReader reading process is asynchronous,
// it's better to get the latest snapshot state
// (i.e., prevState) and update it.
this.setState((prevState) => ({
uploadingImages: [
...prevState.uploadingImages,
{ id: thumbnailTmpId, src: e.target.result },
],
}));
};
reader.readAsDataURL(file);
// ! ! !
//
// This is the uploadImageThunk
//
// ! ! !
onImageUpload(thumbnailTmpId, file);
return file;
});
}
// ... Other code
render() {
const {
change,
currentItemModel,
handleSubmit,
disableButton,
isWorking,
toggleEditing,
fieldIsVariable,
specificsMap,
} = this.props;
const { openVariantsBuilder, uploadingImages } = this.state;
const buttonLabel = currentItemModel ? 'Aggiorna' : 'Crea';
const itemImages = null !== currentItemModel ? currentItemModel.itemImages : [];
return (
// "handleSubmit" is the prop passed by the parent component as exactly "onSubmit"
// https://github.com/erikras/redux-form/issues/1270#issuecomment-239636759
<form onSubmit={handleSubmit}>
<div id="Item" className="container">
<div className="row">
<div className="col-sm-4">
<div className="Section boxed rounded">
<div className="row">
<div className="col-12">
<Field
name="newImages"
component={RenderField}
type="dropzone"
handleOnDrop={this.onDrop}
idPrefix={idPrefix}
className="form-control-sm"
disabled={isWorking}
accept="image/*"
/>
</div>
</div>
<div className="row">
<div className="col-12">
<ImagesGrid uploadingImages={uploadingImages} images={itemImages}/>
</div>
</div>
</div>
</div>
<div className="col-sm-8">
<div className="Section boxed rounded">
<div className="row">
<div className="col-sm-12">
<Field
component={RenderField}
name="title"
type="text"
placeholder="Nome"
idPrefix={idPrefix}
className="form-control-sm"
disabled={isWorking}
label="Nome"
/>
</div>
</div>
</div>
</div>
</div>
</div>
<div className="row">
<div className="col-sm-12 text-center">
<button type="submit" className="btn btn-primary btn-sm" disabled={disableButton}>
{buttonLabel}
{isWorking && <Spinner/>}
</button>
{currentItemModel ? (
<button
type="button"
className="btn btn-outline-primary btn-sm"
onClick={() => toggleEditing({ id: currentItemModel.id, editing: false })}
>
Cancel
</button>
) : (
''
)}
</div>
</div>
</form>
);
}
}
In this component, note two things:
In onDrop() method I call onImageUpload(): this is the thunk uploadImageThunk()
To render a field I use the component RenderField.
The uploadImageThunk()
// ...
export function uploadImageThunk(thumbnailTmpId, ImageFile, currentModel) {
return (dispatch, getState) => {
const callbacks = [];
const onUploadProgress = (progressEvent) => {
const progress = Math.round((progressEvent.loaded * 100) / progressEvent.total);
dispatch(uploadImageProgressAction({ id: thumbnailTmpId, progress }));
return progress;
};
callbacks.push({ name: 'onUploadProgress', callback: onUploadProgress });
dispatch(uploadImageUploadingAction({ id: thumbnailTmpId, uploading: true }));
const token = ctxGetUserToken(getState());
const account = dbGetAccountDetails(getState());
const ImageData = new FormData();
ImageData.append('file', ImageFile);
const placeholders = [{ replace: '__account__', value: account.id }];
return upload(
FILE_IMAGE_UPLOAD_ENDPOINT,
token,
placeholders,
HTTP_POST,
ImageData,
[],
callbacks
)
.then((response) => {
dispatch(uploadImageUploadingAction({ id: thumbnailTmpId, uploading: false }));
return response.data;
})
.then((data) => {
dispatch(uploadImageSuccessAction(data));
return data;
})
.catch((e) => {
dispatch(uploadImageUploadingAction({ id: thumbnailTmpId, uploading: false }));
if (e instanceof SubmissionError) {
dispatch(uploadImageErrorAction({ id: thumbnailTmpId, error: e.errors._error }));
throw e;
}
dispatch(uploadImageErrorAction({ id: thumbnailTmpId, error: e.errors._error }));
});
};
}
The RenderField component
const RenderField = (props) => {
const {
disabled,
input,
meta,
placeholder,
required,
type,
prepend,
prependclass,
options,
defaultOption,
renderAsColorField,
specificColorValues,
changeHandler,
checkboxState,
handleOnDrop,
} = props;
let { idPrefix, labelClasses, label, className } = props;
// Coercing error to boolean with !! (https://stackoverflow.com/a/29951409/1399706)
const hasError = meta.touched && !!meta.error;
if (hasError) {
props.input['aria-describedby'] = `${props.idPrefix}_${props.input.name}_helpBlock`;
props.input['aria-invalid'] = true;
}
idPrefix = null === idPrefix ? '' : `_${idPrefix}`;
const id = `${idPrefix}_${input.name}`;
let RenderingField = null;
let fieldContainerClasses = `form-group${hasError ? ' has-error' : ''}`;
// ...
switch (type) {
// ...
case 'dropzone':
RenderingField = DropZoneField;
break;
default:
throw new Error(`Unrecognized field ${type}. Allowed types are: "text", "textarea".`);
}
return (
<div className={fieldContainerClasses}>
{/* The checkbox has the implementation of labels and errors directly in the component */}
{label && 'checkbox' !== type && (
<label htmlFor={id} className={labelClasses}>
{label}
</label>
)}
{hasError && 'checkbox' !== type && (
<span className="help-block" id={`${idPrefix}_${input.name}_helpBlock`}>
{meta.error}
</span>
)}
<RenderingField
{...input}
type={type}
required={required}
placeholder={placeholder}
disabled={disabled}
id={id}
className={className}
prepend={prepend}
prependclass={prependclass}
options={options}
defaultoption={defaultOption}
specificColorValues={specificColorValues}
renderAsColorField
changeHandler={changeHandler}
label={label}
state={checkboxState}
handleOnDrop={handleOnDrop}
/>
</div>
);
};
The DropZoneField component
The component that actually handles the drag 'n' drop is this:
const DropZoneField = (props) => {
const { handleOnDrop } = props;
return (
<Dropzone onDrop={handleOnDrop}>
{({ getRootProps, getInputProps, isDragActive }) => (
<section>
<div {...getRootProps()}>
<input {...getInputProps()} />
<div
className={`text-center dropzone-area rounded ${
isDragActive ? 'dropzone-drag-active' : 'dropzone-drag-not-active'
}`}
>
{isDragActive ? (
<p className="dropzone-text">
Ora rilascia le immagini per caricarle nel prodotto.
</p>
) : (
<p className="dropzone-text">
Sposta qui le immagini o clicca per selezionarle dal tuo computer.
</p>
)}
</div>
</div>
</section>
)}
</Dropzone>
);
}
Now, the two parts works each one on its own:
The file is correctly uploaded
When saving the form, the entity is correctly saved
What I cannot achieve is to send, along with the entity's information, also the resource URIs of the just uploaded files.
I cannot find a path to add the resource URIs to the field in redux-form.
I read some articles online and found some good answers here on StackOverflow, but, after trying, I'm failing: none of them clarified me which path to follow and how to pass data from the callback method Form.onDrop() to the field newImages in the Form.
Any help is much appreciated as I'm struggling with this for many days.
Please, keep in mind one last thing: this flow will be used in many places and with many different entitites. The endpoint to upload the files is always the same while the forms and the endpoints of the entities will be many and different from one to the other.
Thank you very much for reading until here, also if you don't have an answer for me.
I'm trying to update my category. I want to update only categoryname, categoryDescription and categoryImage inside the category data. For this, I pull the data from the API with the id I wrote in c# on the backend to show the first state of the data to the user, there is no problem there, but when I try to make changes to a data, nothing appears on the screen in the browser and the following errors appear in the console. Actually ı am new in react. How can I fix that problem?
ERRORS
Uncaught TypeError: Cannot read properties of undefined (reading 'categoryName')
The above error occurred in the <UpdateCategory> component:
My CategoryList.js
I send the id of the category I clicked to UpdateCategory.js from here and I do the editing there.
CategoryList.js shows only my categories
import { Button } from "bootstrap";
import React, { useContext } from "react"
import { Link, Router } from "react-router-dom";
import { CategoryContext } from "../Contexts/CategoryContext";
import "../Css/Categories.css"
export default function CategoryList() {
const { Categories } = useContext(CategoryContext)
const truncateOverview = (string, maxLength) => {
if (!string) return null;
if (string.length <= maxLength) return string;
return `${string.substring(0, maxLength)} ...`;
}
return (
<div className="categories">
{Categories.map((category, i) => (
<Link className="category" to={`/ProductList/${category.categoryId}`} key={i}>
<div className="inner-category">
<div className="image-body">
<img src={category.categoryImage} className="image" alt="" />
</div>
<div className="category-body">
<div>
<h5 className="">{category.categoryName}</h5>
<p className="">{truncateOverview(category.categoryDescription, 50)}</p>
<Link to={`/UpdateCategory/${category.categoryId}`}>
<button className ="btn btn-warning" variant="primary" >
EDIT
</button>
</Link>
</div>
</div>
</div>
</Link>
))}
</div>
)
}
My UpdateCategory.js
import React, { useState, useEffect } from 'react';
import { useParams } from 'react-router-dom';
import Button from 'react-bootstrap/Button';
import Col from 'react-bootstrap/Col';
import Form from 'react-bootstrap/Form';
import InputGroup from 'react-bootstrap/InputGroup';
import Row from 'react-bootstrap/Row';
import axios from 'axios';
export default function UpdateCategory() {
const { id } = useParams()
const url = `http://localhost:64082/api/categories/getbyid/${id}`
const [category, setCategory] = useState({})
const fetchData = () => {
axios.get(url)
.then(response => {
setCategory(response.data)
})
.catch(error => {
console.log(error)
})
}
useEffect(() => {
fetchData()
});
const handleInputChange =(e)=>{
setCategory(e.target.category)
}
const handleSubmit = (event) => {
event.preventDefault();
const data = new FormData(event.target);
fetch(`http://localhost:64082/api/categories/update`, {
method: 'POST',
body: data,
})
}
return (
<div>
<form >
<label htmlFor="inputName">Category Name</label>
<input type="text"
className="form-control"
name="categoryName"
value={category.categoryName}
onChange={handleInputChange}
/>
<label htmlFor="inputName">Category Description</label>
<input type="text"
className="form-control"
name="categoryDescription"
value={category.categoryDescription}
onChange={handleInputChange}
/>
<label htmlFor="inputName">Category Image</label>
<input type="text"
className="form-control"
name="categoryImage"
value={category.categoryImage}
onChange={handleInputChange}
/>
<div>
<button onSubmit={handleSubmit} className="btn btn-danger" >EDIT</button>
</div>
</form>
</div>
)
}
The error probably comes about because of the render in UpdateCategory. The code tells it to render three properties of the category object. But initially, category is an empty object. So it will fail there.
There's another point you need to modify though, in the useEffect(). What you have right now will not trigger on the initialisation of the component. Change it to:
useEffect(() => {
fetchData()
}, []);
Since you're not using typescript you'd also probably want some kind of guard on your render to be safe. So for example something like this:
return category.categoryName && category.categoryDescription && category.categoryImage && (
// your render code in here
);
But that's quite long-winded. You could write an if clause before the return () for the render, asking if those properties exist and returning a blank component instead, or some alternate text.
You could also perhaps provide a default version of the category when initialising the hook.
const [category, setCategory] = useState({
categoryName: 'Default',
categoryDescription: 'Default description',
categoryImage: null
});
This would be a simpler effort than the guard block, and you'd still need the useEffect update.
In UpdateCategory.js,edit;
const [category, setCategory] = useState([]) // not useState({})
The default value of this state should be an empty array. Thanks to empty array, It will not be able to return with map until data comes from api, because its length is 0.
Getting below error:
Unhandled Rejection (Error): Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
My Sign In Form
export const SignInView: FC<{ path: string }> = (): ReactElement => {
type Inputs = {
userId: string;
};
function fetchUser(id: string): UseQueryResult {
return useQuery('fetchUser', async () => {
const response: Response = await fetch("http://localhost:8080/users/" + id, RequestInit = {method: 'GET'});
return response;
});
}
const { register, handleSubmit, getValues, errors, setError } = useForm<Inputs>();
const onSubmit = (): void => {
const { userId } = getValues();
//throws Invalid hook call. Hooks can only be called inside of the body of a function component
const { data } = fetchUser(userId);
//....some logic here.
}
return (
<div className='container container-rounded border w-25 bg-white text-center'>
<div className='row p-2 mt-2 text-center'>
<div className='col'>
<p className='h3' data-content='header'>
Demo
</p>
</div>
</div>
<div className='row p-2'>
<div className='col'>
<h5>Sign in</h5>
</div>
</div>
<Form onSubmit={handleSubmit(onSubmit)}>
<div className='row'>
<div className='col form-group'>
<Form.Control
type='text'
name='userId'
autoFocus
ref={register({ required: true })}
className='form-control form-control-lg'
placeholder='User ID'
data-field='userId'
/>
</div>
</div>
<div className='row p-2'>
<div className='col text-center'>
<Button
type='submit'
className='default btn btn-primary btn-lg btn-block button-rounded'
data-action='sign-in'>
Sign in
</Button>
</div>
</div>
</Form>
)
I have seen suggestions that say useMutation instead and invoke mutate callback function but this is a GET call, so useQuery is more appropriate in this case.
The error is correct as you are trying to call the hook not inside the body of the <SignInView /> component.
As you are returning a useQuery hook from your fetchUser function it's also a react convention to use the "use" prefix for your custom hook, so you can call it just useUser.
You can get your use case to work by invoking the call to your api manually. Just set the query's enabled config option to false and trigger the fetch by using refetch in your onSubmit callback.
Then use RHF's watch to pass the current value of your <Form.Control /> to your useUser hook.
function useUser(id: string): UseQueryResult {
return useQuery('fetchUser', async () => {
const response: Response = await fetch("http://localhost:8080/users/" + id, RequestInit = {method: 'GET'});
return response;
}, { enabled: false });
}
export const SignInView: FC<{ path: string }> = (): ReactElement => {
const { register, handleSubmit, errors, setError, watch } = useForm<Inputs>();
const userId = watch('userId');
const { refetch } = useUser(userId);
const onSubmit = async (): void => {
const { data } = await refetch();
//....some logic here.
}
return (...);
}
I am trying to implement eye/eyeslash in on my Register form in React.
This is a function that's is responsible for changing visibility type and eye icon changing.
import React, { useState } from "react";
import { FontAwesomeIcon } from "#fortawesome/react-fontawesome";
export const usePasswordToggle = () => {
const [visible, setVisibility] = useState();
const Icon = <FontAwesomeIcon icon={visible ? "eye-slash" : "eye"} />;
const InputType = visible ? "text" : "password";
return [InputType, Icon];
};
I am trying to implement it in component responsible for registering.
import React, { Component, createRef } from "react";
import { usePasswordToggle } from "./usePasswordToggle";
class Register1 extends React.Component {
EmailR = createRef();
UsernameR = createRef();
PasswordR = createRef();
PasswordConfirmR = createRef();
constructor(props) {
super();
this.state = {
message: "",
password: "",
confirmPassword: "",
};
}
handleSubmit = (event) => {
// alert(this.PasswordR.current.value);
// alert(this.PasswordConfirmR.current.value);
if (this.PasswordR.current.value !== this.PasswordConfirmR.current.value) {
alert("The passwords doesn't match");
return false; // The form won't submit
} else {
alert("The passwords do match");
return true; // The form will submit
}
};
onCreateAccount = () => {
let loginInfo = {
Username: this.UsernameR.current.value,
Email: this.EmailR.current.value,
Password: this.PasswordR.current.value,
};
fetch("http://localhost:5000/api/authenticate/register", {
method: "POST",
headers: { "Content-type": "application/json" },
body: JSON.stringify(loginInfo),
})
.then((r) => r.json())
.then((res) => {
if (res) {
this.setState({
message:
"New Account is Created Successfully. Check your email to verify Account.",
});
}
});
};
render() {
return (
<div>
<h2 className="FormDescription">
{" "}
Please enter Account details for registration
</h2>
<div className="Form">
<p>
<label>
Email: <input type="text" ref={this.EmailR} />
</label>
</p>
<p>
<label>
Username: <input type="text" ref={this.UsernameR} />
</label>
</p>
<div>
<label>
Password:{" "}
<input type={usePasswordToggle.InputType} ref={this.PasswordR} />
</label>
<span className="password-toogle-icon">
{usePasswordToggle.Icon}
</span>
</div>
<p>
<label>
ReenterPassword:{" "}
<input type="password" ref={this.PasswordConfirmR} />{" "}
</label>
</p>
<button onClick={this.handleSubmit}> Create </button>
<p>{this.state.message}</p>
</div>
</div>
);
}
}
export default Register1;
My password is always visible, and eye icon is even not visible on the form (it should be inside my input field, but it is not).
Focus on this code snippet:
<div>
<label>
Password: <input type={usePasswordToggle.InputType} ref={this.PasswordR} />
</label>
<span className="password-toogle-icon">{usePasswordToggle.Icon}</span>
</div>
Any suggestion what is the problem?
Change this
const [visible, setVisibility] = useState();
to this
const [visible, setVisible] = useState(true);
as the official documentation here
First, add a default value to your useState, either true or false depending on which icon you want to render first.
Then, you should add a onClick method to your icon which will toggle the visibility state. You're setting the icon based on visible value, but you never toggle the value.
onClick={() => setVisibility(!visible)}
UPDATE
You also need to execute your Hook inside your main component (because yes, you wrote what React call a Hook), like so :
const [inputType, icon] = usePasswordToggle();
But doing so, you'll get an error from React that say you cannot use a Hook within a class component due to how they work.
Basically you need to change your Register1 component to be a functional component, and not a class anymore. Look here for a quick overview on how to : https://reactjs.org/docs/components-and-props.html
Below is my RequestAnInvite redux-form. The problem is when I submit the form, submitting is never changed to true. You can see I have a log below, which is always outputting false.
What am I doing wrong with redux-form to cause submitting to never set to true when I submit the form?
class RequestAnInvite extends React.Component {
componentDidMount() {
this.props.dispatch(loadTitles());
}
handleSubmit(data) {
console.log(data);this.props.dispatch(requestInvitationsActions.createInvitationRequest(data));
}
render() {
const { handleSubmit, submitting } = this.props;
console.log('submitting: ' + submitting);
return (
<div className="container-fluid h-100">
<form onSubmit={handleSubmit(this.handleSubmit.bind(this))}>
<Field
name="email"
type="text"
component={renderField}
label="Email"
placeholder="xxx#acme.com"
/>
<p>submitting: {submitting}</p>
<div className="form-group form-group-actions">
<button type="submit" className="btn btn-primary" disabled={submitting}>
{submitting ? 'Requesting...' : 'Request an Invite'}
</button>
</div>
</form>
</div>
);
}
}
RequestAnInvite = reduxForm({
form: 'RequestAnInvite',
validate,
})(RequestAnInvite);
const mapStateToProps = state => {
return {
titles: state.titles
};
};
const mapDispatchToProps = (dispatch) => bindActionCreators({
...requestInvitationsActions,
}, dispatch)
export default connect(mapStateToProps, mapDispatchToProps)(RequestAnInvite);
Update 1
handleSubmit(data) {
this.props.createInvitationRequest(data)
.then((response) => {
console.log(response)
}, (error) => {
});
}
From redux-form docs:
Whether or not your form is currently submitting. This prop will only work if you have passed an onSubmit function that returns a promise. It will be true until the promise is resolved or rejected.
Your handleSubmit is just dispatching an action so it has no way of knowing when it is submitting