davidkpiano / react-redux-form

Create forms easily in React with Redux.
https://davidkpiano.github.io/react-redux-form
MIT License
2.07k stars 251 forks source link

Error state should be reset at onChange #596

Open Fr33maan opened 7 years ago

Fr33maan commented 7 years ago

Hi, I have a Control with an async validator, something very classic directly used from doc.

          <Errors
            className="errors"
            model=".email"
            messages = {{
              available  : val => `${val} is already used. Please choose another address`
            }}
          />
          <label>Email</label>
          <Control.text
            type="email"
            model=".email"
            validators={{
              required: val => val.length,
              isEmail
            }}
            asyncValidators={{
              available: (val, done) => actions.checkEmailAvailability(val).then(done)
            }}
          />

Normal behaviour is to check onBlur so I put my already used email address, blur and the error show. Everything fine.

Problem comes when I try to change my email input. I focus, then change the email address ... but the error does not disapear. Even worst, the message is updated with the new value let me thinking that everything I type is not valid. I just discovered this so I don't have found a workaround, do you have an idea to set async validators to true on change ?

davidkpiano commented 7 years ago

I just published 1.5.1 - can you use that and see if the issue still exists?

Fr33maan commented 7 years ago

Just tried it right now and I still have the problem.

Thanks for your help. Easiest workaround right now is to trigger validation also on change but it is not what I would prefer for production :s

davidkpiano commented 7 years ago

A stopgap for now (while I look into this issue) is to do something like this:

dispatch(actions.resetValidity('your.model', ['available']))

That will reset the validity only for the specified keys (in this case, 'available').

Fr33maan commented 7 years ago

Works perfectly. Not very elegant but efficient, thanks for your solution. If people has the same problem, there is my code without unecessary information.

Feel free to close the issue if you consider it as solved or left it open if you consider this need to be changed/fixed.

@connect()
export default class SignInForm extends Component {
  constructor(props){
    super(props)
    this.resetError = this.resetError.bind(this);
  }

  resetError(event){
    const field = event.target.name
    this.props.dispatch(form_actions.resetValidity(field), ['available'])
  }

  render() {
    return (
      <Form model="signUp">
          <label>Username</label>
          <Control.text
            type="text"
            model=".username"
            asyncValidators={{
              available: (val, done) => actions.checkUsernameAvailability(val).then(res => done(res))
            }}
            onChange = {this.resetError}
          />
          <Errors  className="errors"  model=".username"  messages = {{ available  : val => `${val} is already used. Please choose another username`}}  wrapper="span"/>
      </Form>
    )
  }
}
davidkpiano commented 7 years ago

I'll keep this open as I'd like to add an actions.resetAsyncValidity action.

davidkpiano commented 7 years ago

On second thought, would it make sense for async validity to automatically be reset when a field changes?

fidiego commented 6 years ago

@davidkpiano

WRT:

On second thought, would it make sense for async validity to automatically be reset when a field changes?

I think so. I'm having the same problem as the original author. I think it would make sense for the validity to be reset on change.