question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[6.2.0] initialize(currentFormData) clears warnings and errors until the next onChange

See original GitHub issue

Ok, 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:closed
  • Created 7 years ago
  • Comments:10 (8 by maintainers)

github_iconTop GitHub Comments

1reaction
bmv437commented, Nov 18, 2016

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 firing updateSyncWarnings().

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:

...
    var result = empty; // clean all field state
    // keep old warnings, they will get recalculated if the form values are different from current values
    const warning = getIn(state, 'warning')
    if (warning) {
      result = setIn(result, 'warning', warning)
    }
    const syncWarnings = getIn(state, 'syncWarnings')
    if (syncWarnings) {
      result = setIn(result, 'syncWarnings', syncWarnings)
    }
...

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.

0reactions
lock[bot]commented, Jun 2, 2018

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.

Read more comments on GitHub >

github_iconTop Results From Across the Web

[6.2.0] initialize(currentFormData) clears warnings and errors ...
Since the form has yet to be initialized, the INITIALIZE action is fired, setting the form's state to include initial and values (and...
Read more >
Solved: onChange error message - ServiceNow Community
Solved: I have an error message that sudent appears on my publication form, cannot identify why. The error in question is " onChange...
Read more >
React SetValues When input onChange event happen reload ...
I have an issue with the setValues in handleChange function, after the first onChange Event happens the form seems to reloaded and can't...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found