Comments (50)
Works perfectly with async/await
onSubmit={async event => {
await handleSubmit(event)
form.reset()
}}
I tried various suggestions to reset the form on successful submission but to no avail. I was just about to give up on Final Form and move back to Formik.
But then I tried my luck with async/await and it works like a charm!
Thanks Final Form 🥇
from react-final-form.
Final-form
introduced new type in 4.20 version
https://final-form.org/docs/final-form/types/FormApi
Quote from docs:
"restart
() => void
Resets all form and field state. Same as calling reset() on the form and resetFieldState() for each field. Form should be just as it was when it was first created."
Example code:
const onSumbit = form => setTimeout(() => form.restart())
or with destructuring
const onSumbit = { restart } => setTimeout(() => restart())
from react-final-form.
Once the fix in #32 is released, the answer is:
<Form
onSubmit={onSubmit}
initialValues={{ employed: true }}
render={({ handleSubmit, reset }) => (
<form
onSubmit={event => {
handleSubmit(event).then(() => {
reset() // or could be passed directly to then()
})
}}
>
...
</form>
}/>
from react-final-form.
Not sure if i am doing something wrong.
However - form.reset
used as described above indeed resets its values but does not reset field state. Which results in validation errors after the submission.
So what I have to do is to reset each individual field state manually like:
handleSubmit(ev)?.then(() => {
form.reset();
form.resetFieldState("amount");
form.resetFieldState("ingredient");
});
So either I am missing some prop (which I don't seem to see in docs) which would reset not only values but also whole field state or form.reset
does not work as one would expect.
from react-final-form.
@erikras wouldn't be best to pass the reset
or maybe others helpers to onSubmit
.
the signature would be like :
onSubmit: (values: Object, callback: ?(errors: ?Object) => void, reset: Function, ....) => ?Object | Promise<?
from react-final-form.
when i use
<Form
onSubmit={values => {
console.log("values, ", values)
}}
render={({ handleSubmit, form }) => (
<form
onSubmit={async event => {
await handleSubmit(event)
form.reset()
}}
>
because of that
form.reset()
my errors for validation are not shown.
from react-final-form.
Not sure if the best way to proceed with this but you can set a ref on the form instance and on your onSubmit callback fn access the forms reset prop as such
onSubmit = values => {
this.refs["user-form"].form.reset()
};
from react-final-form.
I wanted my form to reset fields after form is successfully submitted. This is the solution working in my case:
<Form onSubmit={this.onSubmit}>
{({handleSubmit, form, submitSucceeded, values}) => {
if (submitSucceeded) {
form.reset();
Object.keys(values).forEach(field => form.resetFieldState(field));
}
return (
< form onSubmit = {handleSubmit} >
...
</ form>
)
}}
</Form>
It's a pitty form.reset() does not automatically turn fields touched property to false, which for my form results showing validation errors (fields are required).
from react-final-form.
EDIT: solved by just putting form.reset() in my handleSubmit method
I have form where I am not accessing event at all and I have problem resetting form after it has been submitted.
I did try this, but form gets reset before it is submitted. As for validation - errors show up, but after that form resets anyway.
onSubmit={() => {
handleSubmit(values).then(reset);
}}
I also tried other aforementioned options, but without any success.
Here is the relevant code from my form :
handleSubmit(values) {
console.log(values.firstName);
//Setting up values for fetch body
let firstName = values.firstName;
let email = values.email;
let subject = values.subject;
let message = values.message;
fetch('/contact/send', {
method:'POST',
headers:{
'Accept':'application/json, text/plain, */*',
'Content-Type':'application/json'
},
body:JSON.stringify({
firstName:firstName,
email:email,
subject:subject,
message:message,
}),
})
.then(res=>res.json())
.then(console.log('here'))
.then(data=>console.log(data))
.catch(err=>console.log(err));
};
render() {
return (
<div className="contact">
<div className="contact__form">
<Form
onSubmit={this.handleSubmit}
validate={values => {
const errors = {};
if (!values.firstName) {
errors.firstName = "Required";
}
if (!values.subject) {
errors.subject = "Required";
}
if (!values.email) {
errors.email = "Required";
} else if(!values.email.match( /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/)) {
errors.email = "Please enter a valid e-mail adress"
}
if (!values.message) {
errors.message = "Required";
}
return errors;
}}
render={({ handleSubmit, submitting, values, reset}) => (
<form
onSubmit={handleSubmit}
>
<Field name="firstName">
{({ input, meta }) => (
<div>
<input {...input}
type="text"
placeholder="Name"
/>
{meta.error && meta.touched && <span>{meta.error}</span>}
</div>
)}
</Field>
....REST OF THE FIELDS
from react-final-form.
Fix published in v1.1.1
.
from react-final-form.
We really could use a handler to clear the contents of the form but does not affect form states like submitSucceeded which are often used to display a success message.
from react-final-form.
Regarding @golestanirad post on validation errors not showing - I had the same problem and it took me a while to find the solution. I think it's not because of form.reset(). In my case, when I had validation errors, async handleSubmit was not executed at all and returned undefined, then form reset was executed. What worked for me was checking if handleSubmit is undefined or returns empty object before resetting the form.
from react-final-form.
Funcionou dessa forma
const onSumbit = (value,form) => { console.log(values) setTimeout(form.reset) }
from react-final-form.
There is no more need to do this kind of workaround, I made a PR that allows the reset during the submission: https://github.com/final-form/final-form/pull/363/files#diff-582693474d2a90e13161b9d64da11dd53a1e4a811df74d614d87463fffa1c8d7
You can now simply do:
const onSubmit = (values, form) => {
// what do you want
form.reset();
}
from react-final-form.
This is still not working for me on latest version.
<Form
onSubmit={values => {
return new Promise((res, rej) => {
axios.post('/api/forms/creditdebit', values)
.then(response => res())
.catch(error => res({ error }));
})
}}
validate={validate}
component={CreditDebitForm}
/>
<Form onSubmit={event => {
handleSubmit(event).then(() => {
reset()
})
}}>
I get: TypeError: Cannot read property 'then' of undefined. Tried using async too with no luck. It submits, so it is calling.
from react-final-form.
@NYCJacob Make sure your code looks something like this (following @Aeon-Avinash's example). It's working for me:
<Form
onSubmit={values => {
console.log("values, ", values)
}}
render={({ handleSubmit, form }) => (
<form
onSubmit={async event => {
await handleSubmit(event)
form.reset()
}}
>
from react-final-form.
I have the same problem of the @tomkis.
When call setTimeout(form.reset)
the global form state is cleared, but the fields states stay with touched
and others properties preserved.
A very ugly solution is to call form.resetFieldState
for all fields.
const onSubmit = useCallback(async (values, form) => {
try {
await axios.post(...);
setTimeout(() => {
Object.keys(values).forEach(key => {
form.resetFieldState(key);
});
form.reset();
});
} catch (err) {
...
}
}, []);
return (
<Form
onSubmit={onSubmit}
render={...}
/>
);
from react-final-form.
Spoke too soon. Still not working. Cannot read property 'then' of undefined. @erikras
const onSubmit = (values, user) => {
return new Promise(resolve => {
axios.post('/api/forms/samples', { values })
.then(response => resolve())
.catch(error => resolve({ error }));
});
}
const FormContainer = ({ user }) => {
return (
<Form
onSubmit={(values) => onSubmit(values, user)}
mutators={{
...arrayMutators
}}
initialValues={{ products: [{ placeholder: null }] }}
validate={validate}
component={SamplesForm}
/>
);
}
<form onSubmit={event => {
handleSubmit(event).then(() => reset())
}}>
from react-final-form.
I'm not sure this code is the best way but it's working for me:
import React from 'react';
import { Form } from 'react-final-form';
const Component = () => {
let handleResetForm = null;
const handleSubmitForm = () => {
// Do something...
handleResetForm();
};
return (
<Form
onSubmit={handleSubmitForm}
render={({ handleSubmit, pristine }) => {
// Referenced the reset method to out of the form
if (!handleResetForm && form && form.reset) {
handleResetForm = form.reset;
}
return <form onSubmit={handleSubmitForm}> ... </form>;
}}
/>
);
}
"final-form": "^4.18.5"
"react-final-form": "^6.3.0"
from react-final-form.
I do it this way:
const [formKey, setFormKey] = useState(Date.now());
...
<Form
key={formKey}
...
onSubmit={() => {
// save to server
setFormKey(Date.now());
}}
/>
from react-final-form.
Here's a working sandbox with my suggestion from above.
Doesn't seem to work with final-form 4.20.1 and react-final-form 6.5.1. @erikras
Solved it using the second argument of onSubmit
function which is the form.
const onSubmit = async (values, form) => {
handleCalculate();
setTimeout(() => form.initialize({}), 10);
form.resetFieldState("amount_known");
form.resetFieldState("used_electricity_amount");
}
<Form
onSubmit={onSubmit}
or form.restart()
seems to reset all the fields too.
Another way that works is using form.reset()
in the render prop of Form
<Form
onSubmit={onSubmit}
render={({ handleSubmit, values, form }) => (
< form
className='form'
id='real-estate-form-2'
onSubmit={event => handleSubmit(event).then(() => {
form.reset();
})}>
from react-final-form.
Hi @davidhenley i managed to make it work see this example :
https://stackblitz.com/edit/react-final-form-reset-submit?file=index.js
from react-final-form.
@stunaz I completely agree. Especially we already have callback
, which de facto is just setSubmitError action, so why not to add other actions, like reset
.
@erikras the problem with your promise solution is, that this is not always possible. For instance, when you use redux-saga instead of redux-thunk, you wont have promise at your disposal, so it is necessary to have a reset
in onSubmit
itself, so it could be passed to saga there for a later execution.
from react-final-form.
Solved putting form.reset() in the parent component
from react-final-form.
@soroushchehresa quick notes:
- you are reassigning a const variable.
- you should add
form
in the render prop function
This should be enough:
<form onSubmit={handleSubmit.then(form.reset)}>
from react-final-form.
I think that this is the best practice.
final-form handleSubmit method has 3 parameters, values, form and callback.
You need to point which method will be called on callback,, and you can add form.reset for that.
In this sample, I'm collecting only edited values, and sending them to my handleFormSubmit
async method.
<Form
validate={validateFields}
onSubmit={(values, form, callback) => {
// eslint-disable-next-line no-param-reassign
callback = form.reset;
const changedValues = {};
Object.keys(form.getState().dirtyFields).forEach(propName => {
changedValues[propName] = values[propName]
});
return handleFormSubmit(changedValues);
}}
from react-final-form.
const handleSubmitForm = (values, action) => {
console.log("Form values", values)
CALL_AN_API.then((res) => {
action.resetForm(); // Reset the form to initialValues
})
};
<Formik
initialValues={initialValues}
onSubmit={handleSubmitForm}
validationSchema={validationSchema}
enableReinitialize
>
....
</Formik>
from react-final-form.
@hdrdavies I get the form to reset, but that just clears the form. I would like to display some kind of success/failure message. I am afraid to try converting the form to a class and use state because final-form is doing so much internally. I was looking at the response object on return but I still need state I think to conditionally render a message.
from react-final-form.
@golestanirad you don't have a form
variable so you're calling reset()
on undefined variable, that must be your issue.
If your destructure form
in render property, then also extract reset
function and call it directly:
#21 (comment)
from react-final-form.
Ah ok. Then I would suggest something like this:
<form
onSubmit={
async (...args) => {
await handleSubmit(...args);
form.reset();
}
}>
from react-final-form.
Remember that your onSubmit
function not only receives values
, but also the form
object:
function MyComponent() {
const mySubmit = useCallback(
(values, form) => {
// Do what you want with your values...
setTimeout(form.restart); // or setTimeout(form.reset())
},
[/* ... */]
);
return (
<Form
onSubmit={mySubmit}
component={MyForm}
/>
);
}
cf. https://final-form.org/docs/react-final-form/types/FormProps#onsubmit
from react-final-form.
Hi @erikras thanks for the fix i will try on my side and upgrade to v1.1.1
from react-final-form.
Try it using component. It still doesn't work for me. This is my one pain with RFF right now. I'll try again tonight.
from react-final-form.
Here's a working sandbox with my suggestion from above.
from react-final-form.
Heads up, you cannot use handleSubmit(e).then(...
unless you disable your submit on invalid. The middleman does not return a promise so there is no .then
from react-final-form.
opened an issue #69 to get more visibility
from react-final-form.
"Uncaught TypeError: Cannot read property 'then' of undefined at onSubmit"
:/
from react-final-form.
Make sure you add return in front of fetch/axios or whatever library you're using to make POST request.
return fetch('/', { method: 'POST'......
from react-final-form.
any examples showing a submit success message to the user by rendering a component rather that an alert window or would that require make a class out of the form
from react-final-form.
As for using reset in onChange() of something inside the form? Anyone have an idea. Please suggest me
from react-final-form.
onSubmit={(event) => {
const promise = handleSubmit(event);
console.log('heyyy :-D', promise);
promise && promise.then(() => {
reset();
})
return promise;
}}
from react-final-form.
@Aeon-Avinash this still doesn't work for me :(
from react-final-form.
- you code will only reset if you handleSubmit is async or excplicitly return a promise (to execute the "?.then" callback)
- What part of field state are you talking about ?
because once the reset is done your validation function get the initialValues, which can be valid or not depending on your validation function
from react-final-form.
ad 1) yes I am well aware of that
ad 2) - i am talking about touched
flag which remains true even after resetting the form - only resetFieldsState
resets it back.
from react-final-form.
I'm seeing the same issue when I tried (here https://codesandbox.io/s/epic-platform-wtm5s)
Maybe you could use "dirtySinceLastSubmit" instead ?
from react-final-form.
@VincentCharpentier Thanks for the notes.
In my case, the handleSubmit
method doesn't return a promise!
from react-final-form.
@VincentCharpentier My handleSubmit
method doesn't return a promise,
So I can't use await
or then
. My suggested example is just for non-async flows, something like using forwarding refs!
Async Functions
Forwarding Refs
from react-final-form.
Wouldn't it make more sense to use form.initialize
so you keep the submitSuccess
state? You can pass an empty object or whatever you previous used for initial values. I think this also sets the form state of pristine
to true again too so you can use that state with submitSuccess
to determine the first submission vs second etc.
const onSubmit = useCallback(
async function onChangePasswordFormSubmit(values, form) {
try {
await updatePassword(values)
// clears focus if submit via enter press
document.activeElement.blur()
// re-initialize form AFTER submitSuccess to prevent re-focus on first field
setTimeout(() => form.initialize({}), 20) // resets form without losing submitSucceeded state
return undefined // triggers submitSuccess state
} catch (error) {
console.error(error)
return mapErrors(error)
}
},
[ updatePassword]
)
from react-final-form.
It depends on the need, everyone can do an initialize
, a reset
or a restart
.
I don't really see the interest of the setTimeout
and the return
here.
from react-final-form.
@bertho-zero has the right idea, but I found that calling form.reset()
clears the form, then runs validation. I found it's better to call form.restart()
because it doesn't run validation. An example use case is a user opens up a dialog with a form, clicks a field, then closes the dialog. Because the field has been touched
, validation may render an error.
Here's my handleSubmit
:
const handleSubmit = async(data, form) => {
setLoading(true);
const result = await doWork(data);
setLoading(false);
handleClose(form);
}
...
const handleClose = (form) => {
onClose();
// if we've been passed a form, restart it to clear without validation
form && form.restart && form.restart();
};
from react-final-form.
Related Issues (20)
- Form Reset When Modal Close HOT 1
- Field State Sync Issue in Strict vs Non-Strict Mode in react-18 HOT 5
- Q: should readonly fields be validated on blur?
- Error in codesandbox example HOT 2
- Documentation for defaultValue of FieldProps is not matching implementation
- Warning message in console when using the field validation for a string field. HOT 3
- Ran into "is dirty" validation issues when state was used to autofill a form's input field. HOT 1
- [Feature Request] Add new prop to specify changes to specific form fields HOT 1
- change is not a function HOT 1
- Rewrite To Typescript HOT 2
- rerenderOnEveryChange for react-final-form
- <FormSpy> components rendering earlier than in previous versions
- DestroyOnUnregister incompatible with StrictMode in React18 HOT 2
- isEqual is initialized by the first field registered instance
- useField does not rerender component, when its props change
- Submitting Images in React Final Form
- I believe defaultValue should be the DEFAULT. That means, if NO initialValue was passed in, the defaultValue would be used. If there is an initialValue, it should override the defaultValue. One work around is using an OR in initialValues and skip using defaultValue all together like so:
- Form not dirty after removing items from FieldArray using final-form-arrays
- Field-Level validation for root and nested fields
- The field errors are still there, but the form errors are gone
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from react-final-form.