Here is the code
import React from 'react';
import PropTypes from 'prop-types';
import { Link, Redirect } from 'react-router-dom';
import { Field, reduxForm } from 'redux-form';
import { connect } from 'react-redux';
import { Section, RenderField, Block } from 'components';
import { validateRegisterForm as validate } from 'utils/validations';
import { forgotPassword } from 'redux/modules/auth';
const mapStateToProps = state => {
const { sending, sendSuccess } = state.auth;
return { sending, sendSuccess };
};
const reduxFormDecorator = reduxForm({
form: 'ForgotPasswordForm',
validate,
});
const reduxConnector = connect(mapStateToProps, { forgotPassword });
class ForgotPassword extends React.Component {
static propTypes = {
sending: PropTypes.bool,
forgotPassword: PropTypes.func.isRequired,
handleSubmit: PropTypes.func.isRequired,
};
static defaultProps = {
sending: false,
sendSuccess: false,
};
componentWillReceiveProps(nextProps) {
if (nextProps.sendSuccess) {
this.props.reset();
}
}
handleFormSubmit = data => {
this.props.forgotPassword(data);
};
render() {
const { handleSubmit, reset, sending } = this.props;
return (
<div>
<Section>
<div className="form-popup">
<div className="form-popup-content">
<Block loading={sending}>
<form
id="register-form"
name="register-form"
method="POST"
onSubmit={handleSubmit(this.handleFormSubmit)}
>
<Field
name="email"
type="email"
component={RenderField}
label="Alamat Email"
description="contoh: [email protected]"
/>
<button type="submit" className="button mid primary m-bottom-25">
Reset
</button>
</form>
</Block>
</div>
</div>
</Section>
</div>
);
}
}
export default reduxConnector(reduxFormDecorator(ForgotPassword));
At first validation works well. but when form is submitted and this.props.reset() is called (the input become empty) and I try to submit it again it not validate the input (input is empty).
Redux form 6.7
React 15.5.4
Having the same issue.
Can anyone create a working example of this, please?
Same for me.
Seems like validate method not triggered in handleSubmit if you reset form before. And after changing any field value all works again
import React from 'react';
import PropTypes from 'prop-types';
import { reduxForm, Field } from 'redux-form';
import { Text } from '../../../components';
import { validatePassword } from '../validation';
const reduxFormDecorator = reduxForm({
form: 'securityForm',
validate: validatePassword,
enableReinitialize: true,
});
const propTypes = {
handleSubmit: PropTypes.func.isRequired,
};
function security({ handleSubmit, reset, success }) {
if (success) {
reset();
}
return (
<div className="form-box-items">
<div className="profile-box form-box-item">
<h4 className="page-title">Keamanan</h4>
<form id="security" name="security" method="POST" onSubmit={handleSubmit}>
<Field
id="oldPassword"
name="oldPassword"
type="password"
component={Text}
divClass="input-container"
/>
<Field
id="newPassword"
name="newPassword"
type="password"
component={Text}
divClass="input-container"
/>
<Field
id="newPasswordConfirmation"
name="newPasswordConfirmation"
type="password"
component={Text}
divClass="input-container"
/>
<button type="submit" className="button mid dark">Save</button>
</form>
</div>
</div>
);
}
security.propTypes = propTypes;
export default reduxFormDecorator(security);
@gustavohenke this is simpler function. after reset the field is not validating.
any issue ???
If you call reset, the next call to defaultShouldValidate returns false.
That's because it compares previous values to new values to see if it needs to validate, but it's comparing initial values with each other because the form has already been reset.
I noticed that the reset action creator doesn't do much. I feel like it should force the form to re-run sync validation. Otherwise I can't think of a way to tell whether reset has run, the next time defaultShouldValidate gets called.
Having the same issue.
Works fine in 6.3.2 and all other versions till 6.5.0. 6.6.0 introduced this change.
Could be due to https://github.com/erikras/redux-form/pull/2584
Could someone confirm if this is still an issue in 7.x?
Here's a replicable example in 7.0.2. https://www.webpackbin.com/bins/-KpqKYZhHDlocf2ToRfv
PR's welcomed!
Is there a workaround for this? I need reset capability on my form but I also need it to not break validations. Is there some other way to reset for now until this is fixed?
@dizlexik I do this instead:
this.props.destroy();
this.props.initialize();
and works perfectly! (redux form injects those methods along with others in your component by default)
Workaround suggested by @pablonm3 works fine indead. Will be using this as long as no fix for reset is present.
Thanks for the suggestion @pablonm3, but I had actually tried that before and it didn't behave any differently than reset for me. I just tried again with the same results. Calling destroy and initialize does reset the form but it has the same effect as reset in that validations stop working. I wonder why this is working for you guys and not me :/
@dizlexik Actually i realized that it just works in some situations, and in others it works the same as calling reset() , i'm still trying to isolate the reason behind all this, if someone has the answer please let us know!
I don't have the time to dig in too deeply at the moment, but have you looked into @stream7's comments from June 28th? Looks promising.
I think it's the same as calling this.props.reset(); just that using other syntax...
did anyone find the workaround for it?
Might be a workaround: Instead of calling reset, do it yourself in the reducer.
Where you put in the formReducer, use the plugin function to intercept an action of your choice in order to reset the form, as such:
const reducer = combineReducers({
form: formReducer.plugin({
fooForm: (state, action) => {
switch (action.type) {
case YOUR_ACTION_HERE:
return {
...state,
values: undefined,
};
default:
return state;
}
},
}),
});
I haven't played around with the other parts of the redux store, but just returning undefined for values had the validation show up for me.
More importantly, the valid/invalid prop stays correct when I do this. For my case, if you return undefined for the entire form state, the validation only runs after user interaction, AND the valid/invalid prop is permanently broken. I have fields in multiple components, with the redux form on the highest component.
@JokingPhantom This works. the values in the form are now undefined and it automatically fires UPDATE_SYNC_ERRORS. Is there a proper way we can prevent it from running automatically?
@jhondelbaguio try explicitly setting more of the redux state that redux form creates - set visited/touched to false, delete the values object completely, delete the sync errors object too.
To be complete, examine the entire state when the form first loads, when all fields are blank and no validation or sync errors have occurred - then set the entire state to that in the plugin function. A complete "reset" so to speak, which the built in reset prop promises but does not deliver.
This work around is working. Make destroyOnUnMount as false. So the syncerrors and the form fields wont be unregistered.
connect(mapStateToProps, mapDispatchToProps)(reduxForm({
form: 'myform',
validate,
destroyOnUnmount: false,
})
in componentWillRecieveProps, again initialize the form
componentWillReceiveProps(nextProps) {
if (this.props.popUpState !== nextProps.popUpState) {
this.props.initialize();
}
}
Now the form is cleared on remounting and validation also works.
I'm using Redux Form 7.1.2 with React 16 and came up with this solution:
shouldError: ({ props }) => {
return !props.anyTouched;
}
@Landish it fires validation and handleSubmit simultaneously
Wow, that actually works. Thanks @Landish!
Is this any indication that the issue may reside in https://github.com/erikras/redux-form/blob/master/src/defaultShouldError.js ?
I'm having trouble understanding exactly what the purpose of shouldError is and how this workaround is working. Seems weird to me that once any fields are touched this returns false but validations still continue to work. Clearly a fundamental misunderstanding on my part but I can't seem to grok this from the documentation :/
@umer4ik
You're right, haven't tested it well I guess.
This one did not call handleSubmit.
shouldError: ({ props }) => {
return props.invalid;
}
P.S. props.invalid is more "correct way", rather than !props.anyTouched.
But with this, _sometimes_ it calls validate twice instead of one on per change and blur.
Does anyone know if a real solution is on the horizon? None of the workarounds are working for me in 7.0.3. I don't even see destroy or initalize in my props. Maybe I'm missing something?
I'm having the same issue.
ReduxForm: 7.1.2
React: 16.0.0
Same issue here with redux-form 7.0.3 and react 16.0.0
@Landish your solution works for me, React 16.0.0 and ReduxForm 7.1.2.
Facing the same issue.
@Landish can you please tell me where I should use 'shouldError'? Searched for it but got no hint.
React: 16.2.0
Redux Form : 7.2.0
Figured it out, but same result, validation not firing after submit.
Hi ! Somebody found solution please ? I need it urgently... Thank you
@Abdul-Moiz-Ansari add it to reduxForm HOC config. https://redux-form.com/7.2.0/docs/api/reduxform.md/#-code-shoulderror-params-boolean-code-optional-
Hi, i have the same problem, someone found some solution
@sabarnix I've added that, but still same issue.
Has someone been able to find a work around for that?
Only workaround I've come up, is to check the values object in form submit method.
Same issue on 7.2.0
What seems to be happening in the Redux log is that the fields are registered twice, and then the form is unmounted/destroyed once, removing the fields from registration.
Is this not what the count in registration is for? Shouldn't @@redux-form/DESTROY just decrease the register count and remove the registration if the field hits 0?
I've also have this problem in 7.2.0. In my case the invalid/valid props were incorrect for disabling the submit button after a form reset. I resolved my issue by manually checking if formSyncErrors exists on the form in redux using the following code.
import { getFormSyncErrors } from "redux-form";
...
const mapStateToProps = (state) => ({ hasErrors: Object.keys(getFormSyncErrors("login")(state)).length > 0 });
export default connect(mapStateToProps)(LoginForm);
export default reduxForm({
form: 'formProductUpdate',
validate,
enableReinitialize: true,
destroyOnUnmount: false,
keepDirtyOnReinitialize: true
})(ProductUpdate);
Still have the issue on redux-form 7.2.3
It's like the sync validation step is never made before any change or (new) register event occurs. (touch does not trigger it)
I have a "wizard" form that does not submit between each step, so my "next" button is being available on first step when it should not. Going "next" does trigger register events, and validation occurs at that time, too late.
I tried using shouldError but it doesn't work as I hoped it should have. I have a isLoading prop that would have been perfect for that (it matches the form initialize() call that have my real values) but when shouldError returns true (once isLoading gets to false), no validation is made ...
I tried shouldValidate (deprecated I know) and it works "a little better": when it returns true for the first time after isLoading gets to false (so shouldValidate is like (props, nextProps) => props.isLoading && !nextProps.isLoading i get my validation correctly.
BUT as I also obviously need to check for changes in my form (so add the defaultShouldError deepEquals as ORs to my isLoading return condition), I get shouldValidate to (and that's normal) return true multiple times during the load. And when finally my form is initialized and isLoading gets to false, no validation is made...
Hope that helps ... :/
EDIT: When I says that I get no validation, I mean @@redux-form/UPDATE_SYNC_ERRORS never occurs and formSyncErrors is empty.
And the field that should raise an error is a required field that is empty, and as soon as I change any value on the form, the @@redux-form/UPDATE_SYNC_ERRORS happens and the error raises in formSyncErrors.
EDIT 2: If a fix could "just" be for shouldError to work as expected that would already be awesome.
Ok after further investigations I've found the cause of my issue (but it's still a bug).
It's related to field disabling:
During loading state all my fields are disabled: the validation seem to not take care of disabled fields, ok, seems logic.
Once my values are loaded fields are all set enabled, but the validation is not re-ran for the required ones.
I guess that's specific and that's why shouldError is available for me. But then I don't know how to use it because when isLoading gets false, fields are getting enabled and rendered after shouldError is executed (react lifecycle).
I think that redux-form should maybe look after fields enable/disable state changes to run validation.
I have a fix for my own issue which is to set my isLoading(false) before redux-form's initialize(...) but I think that's anyway an issue for redux-form because that bug might happen for various reasons.
EDIT: And now I realize that this was maybe not the right issue thread to post that in ...
Ho boy, one thing I forgot about my code is that, on field disabled _I_ removed the required validator.
And so once loaded I set it (so, for the first time) on the fields that need it.
So: form is already mounted and field have a new validator: which is not taken care of.
Sorry for the mess that was a hell of a long investigation, but I think that's still interessting for you guys to know.
Same bug for me
Just use
let { dispatch, change, untouch } = this.props;
dispatch(change('company', ''));
dispatch(untouch('company'));
dispatch(change('position', ''));
dispatch(untouch('position'));
Just change value and untouch^ And can use form again
Same bug here, I've fixed it using the shouldError workaround.
No idea what's happening, I'm just calling reset() on the componentWillMount() hook.
My case was that If a reloaded the page then props.valid was false, reload again and gets true, reload false again, etc. Just a was turning on/off some props upon reloading...
Without shouldError even the redux logs gets mad:
@@INIT
@@router/LOCATION_CHANGE
@@redux-form/UPDATE_SYNC_ERRORS
@@redux-form/RESET
@@redux-form/FORM_SET_VALUES
...and then:
@@INIT
@@router/LOCATION_CHANGE
@@redux-form/RESET
@@redux-form/FORM_SET_VALUES
So the @@redux-form/UPDATE_SYNC_ERRORS gets dispatched intermittently.
:+1: Same issue.
@@redux-form/UPDATE_SYNC_ERRORS never fires are a initialize dispatched
Just to be more specific here, it only happens when i set enable enableReinitialize: true and dispatch a initialize event. If i set enableReinitialize: false but still dispatch the initialize, things works as expected so far. Best.
The solution with re-initializing the form instead of resetting works for me.
Smth like
this.props.dispatch(initialize('formName', initialFormData))
@Landish's work around works for me
shouldError: ({ props }) => {
return !props.anyTouched;
}
however the `props.invalid' doesn't work for my code
I'm also have a problem with this. shouldError: ({ props }) => { return !props.anyTouched; } doesn't work for me. I too am using enableReinitialize. The solution for me was the aforementioned destroyOnUnmount: false workaround.
Checking for errors by calling validate function (given to redux-form) in onSubmit and throwing SubmissionError if any error was what worked for me. Also enableReinitialize: true was set.
The same error, @TheAznShumai solution helped.
import { reduxForm, getFormSyncErrors } from 'redux-form';
import { connect } from 'react-redux';
import Component from './index';
const formConfig = {
form: 'draft',
};
const mapStateToProps = state => ({
hasErrors: Object.keys(getFormSyncErrors(formConfig.form)(state)).length > 0,
});
export default connect(mapStateToProps)(reduxForm(formConfig)(Component));
Then in Component you have to check invalid || hasErrors to disable the button
<button disabled={invalid || hasErrors}>
Submit
</button>
Facing same issue in v7.2.3.
I have the form in a Material UI Dialog. The validation is triggered first time but after closing and re-opening the Dialog, it submits without any data filled. Validation is not triggered.
If I change destroyOnUnmount to false, it works.
My solution was to completely destroy the Material UI dialog on closing it and re-mounting it on opening. No other workaround worked!
Changed
<Dialog open={this.state.open} ......../>
to
this.state.open && <Dialog open={this.state.open} ......../>
fwiw, I was experiencing the same issues but calling initialize instead of reset did the trick for me.
Update: This works but it will not respect any initialValues you set in reduxForm HOC
@pablonm3 You saved my life dude. It works !!!
Using initialize (and passing the initialvalues) worked out for me
@Landish comment of setting ShouldError worked for us. Initially tried changing from .reset() to .destroy() and .initialise() but did not detect any chance in functionality, form would still only validate once (for touched)
I am having the same issue but if I follow the example I can get it to work properly. Seems like you need to disable the clear button disabled={pristine || submitting}.
ReduxForm: 7.4.2
React: 16.4.0
<button type="button" disabled={pristine || submitting} onClick={reset}>
Clear Values
</button>
Another workaround is to put a timestamp in the form's name and instead of calling reset(), update the timestamp when the form is reset. The name change will cause the old form to be destroyed and a new form will initialize with a working validation state.
I'm using Redux Form 7.1.2 with React 16 and came up with this solution:
shouldError: ({ props }) => { return !props.anyTouched; }
saved my day
edit: doesn't work properly bcoz errors still keep appearing when i start to fill the field :(
This is still an issue in "redux-form": "^7.4.2"
workaround seems to be reset(); initialize(initialValues)
@wmertens None of the workarounds here worked in my case. Didn't seem like a special case at all.
Described my case here - https://github.com/erikras/redux-form/issues/2814#issuecomment-459309922
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
UPDATE
Managed to get it working consistently, but with what feels like a workaround.
https://github.com/erikras/redux-form/issues/2814#issuecomment-459356655
In my case (RF v7.4.2) the workaround is
this.setState({showForm: false}, () => this.setState({showForm: true}))
which fully unmounts (removes) form then immediately rerenders again and mounts it again
Strange but simple this.setState({formKey: uuid()}) (where uuid() generates v4 uuid) doesn't work (sometimes @@redux-form/UPDATE_SYNC_ERRORS action is not called in this case)
destroyOnUnmount: false,
keepDirtyOnReinitialize: true
Addind destroyOnmount: false and keepDirtyOnReinitialize: true for me solved the issue. Thanks @stevanus1997 you made my day dude!
For future reference I'm using:
"redux": "^4.0.1",
"redux-form": "^8.1.0",
"react": "^16.8.3",
Almost 2 years passed. Any solid solution? :(
@hamanovich No, destroyOnUnmount: false,
keepDirtyOnReinitialize: true just partially solve the issue, but validation keeps breaking.
@karensantana it doesn't help in my case at all
@pablonm3 I do this instead:
this.props.destroy();
this.props.initialize();
and works perfectly! (redux form injects those methods along with others in your component by default)
I placed form on modal and I run this.props.destroy() this.props.initialize() on handleCancel. It's work for me just 1 times. When I close for second time, ReduxForm not trigger @@redux-form/UPDATE_SYNC_ERRORS
@pablonm3 I do this instead:
this.props.destroy();
this.props.initialize();
and works perfectly! (redux form injects those methods along with others in your component by default)I placed form on modal and I run
this.props.destroy() this.props.initialize()onhandleCancel. It's work for me just 1 times. When I close for second time, ReduxForm not trigger@@redux-form/UPDATE_SYNC_ERRORS
Hi, I'm not sure which frame did you use , I'm using React. And I use it inside ComponentWillReceiveProps, like this:
//visible means the modal's visible state, initialValues means the form's value .when the modal is using for create something ,you can pass {} into initialValues , and when you using for editing something , you can pass some information into initialValues.
public componentWillReceiveProps(nextProps) {
if (!nextProps.visible && this.props.visible) {
this.props.initialize(initialValues);
}
}
use this.props.initialize() instead of using this.props.reset()
2 years and no solid solution. :/
If the form is in Dialog box, destroy it completely as suggested by @shantanupaul here. Worked for my Material UI Dialog too. Does call UPDATE_SYNC_ERRORS.
along the same lines as the solution from @codeBelt https://github.com/erikras/redux-form/issues/2971#issuecomment-400870203, I did something like this:
{dirty && (<button type="button" onClick={reset}>
Clear Values
</button>)}
@codeBelt's solution #2971 is a great workaround. Though it doesn't fix the problem, it provides a way to avoid it. The problem seems to be related to resetting an otherwise pristine form. Hence if the reset button is disabled as long as the form is pristine, the problem can't appear.
"redux-form": "^8.2.6", things haven't got forward an inch(((
I use initialize instead of reset. It works for me.
"redux-form": "^8.2.6"
Solved in my modal case.
I called this.props.destroy() in my handleOpenModal() function and this.props.initialize({ description: ''}) in handleCloseModal().
When I called both in handleCloseModal() it worked only after one modal close.
It's important to add in this.props.initialize(...) at least one field.
To validation i'm using validation prop in reduxForm(...) wrapper.
"redux-form": "^8.2.0",
I solved this by adding
destroyOnUnmount: false,
enableReinitialize: true
to my reduxForm and calling this.props.initialize() to reset after submitting.
I solved this by forcing validation using the shouldValidate config.
```js
reduxForm({
// Set to always validate
shouldValidate: () => true,
// Other config options...
})```
Most helpful comment
I'm using Redux Form 7.1.2 with React 16 and came up with this solution: