[6.2.0] initialize(currentFormData) clears warnings and errors until the next onChange
See original GitHub issueOk, so I’ve tracked this bug all the way down to the cause, I just don’t have a solution. I’d be happy to submit a PR if we can figure out a solution.
A little background:
in src/reduxForm.js
, warnIfNeeded()
will always fire updateSyncWarningsIfNeeded()
on initialRender (nextProps
=== undefined
), but on subsequent renders, it will only fire the updates if !deepEqual(values, nextProps.values)
see the following copy of warnIfNeeded
warnIfNeeded(nextProps) {
const { warn, values } = this.props
if (warn) {
if (nextProps) {
// not initial render
if (!deepEqual(values, nextProps.values)) {
const { _warning, ...nextSyncWarnings } = warn(nextProps.values, nextProps)
this.updateSyncWarningsIfNeeded(nextSyncWarnings, _warning)
}
} else {
// initial render
const { _warning, ...nextSyncWarnings } = warn(values, this.props)
this.updateSyncWarningsIfNeeded(nextSyncWarnings, _warning)
}
}
}
this makes sense for most cases, but what if you initialize the form using the current values of the form (in order to get a pristine state)?
const warn = (values) => {
let warnings = {};
if (!values.message || !values.subject) {
warnings._warning = "missing required fields";
}
return warnings;
}
class MyFormComponent extends Component {
handleSave = (data) => {
this.props.saveData(data);
this.props.initialize(data);
}
handleSend = (data) => {
this.props.sendData(data);
}
render() {
const {pristine, warning, handleSubmit} = this.props;
return (
<div>
<Field name='subject' component='text' />
<Field name='message' component='text' />
<button type='button'
disabled={pristine}
onClick={handleSubmit(this.handleSave)}>
Save Draft
</button>
<button type='button'
disabled={!!warning}
onClick={handleSubmit(this.handleSend})>
Send
</button>
</div>
);
}
}
const MyForm = reduxForm({
form: 'myForm',
warn
})(MyFormComponent);
Since the action handler for the initialize
action starts from an empty state, warnings get cleared from the state. and since it’s not initialRender, and the values of the form haven’t changed, it won’t re-calculate warnings.
We need a way to the form to recalculate warnings even if the form has been initialized to it’s current values in order to achieve a pristine state.
Technically there is a similar issue with sync errors and the validateIfNeeded()
function, but you can’t fire a submit on a form with errors anyway (hence why I’m using warnings).
I’d love to get some discussion going around a solution, and like I said, I’d be happy to submit a PR with the final fix.
Issue Analytics
- State:
- Created 7 years ago
- Comments:10 (8 by maintainers)
Top GitHub Comments
after messing around with this for the later half of the day, removing that !deepEqual check doesn’t solve it, that’s just the first barrier.
The second barrier exists inside
updateSyncWarningsIfNeeded
where it checks to see if the warning is different from the previous warning. It won’t pass that condition since it’s comparing this.props.warning to the recalculated nextWarning, which are the same. So it will end up failing that and not firingupdateSyncWarnings()
.The only solution I’ve come up with is to modify the way the
INITIALIZE
action handler works. currently it starts with a blank slate. I propose we follow that line with the following:This will persist the old warnings through the
INITIALIZE
action, which solves my test case where you are reinitializing the form with its current values. It will also not break the current functionality when you reinitialize with values that are different than the current form values, since that passes the first barrier, and will go and re-calculate warnings.I’ve tested it locally with both cases and it seems to work fine, and it passes all current tests. Thoughts? I can whip up a PR if you approve.
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.