jurassix / react-validation-mixin

Simple validation mixin (HoC) for React.
MIT License
283 stars 38 forks source link

Validation with Flux #52

Closed pdolega closed 8 years ago

pdolega commented 8 years ago

I am trying to migrate application from version 4.x to 5.x. Previously I had everything being handled in Store and results of validation being kept in State.

In some of the cases I handled both regular validations (e.g. fields lengths, max / min values etc) as well as more complex business validations (e.g. existence of particular tuple in db on server side).

As of version 5.x I see that everything (validation results, Joi helper methods) is being stored within props. Now - previously I interacted (on the store side) with validation results, by e.g. adding some custom validation errors. With new version everything is being handled by props object. So basically I am trying to wrap my head around this - how to proceed with such a scenario in version 5.x. I assume I don't want to change props object from within the component itself (or store).

Also I see there is an example in documentation which is probably there to show exemplary validation with flux architecture but it (part of documentation) appears to be exact copy basic example.

Any ideas or best practices on how it might work with Flux architecture ?

PS. Using ES6 style.

jurassix commented 8 years ago

FLUX

The FLUX example from the documentation is just showing that we are expecting your application state to come to the component in the form of props - pulled from a store by a Parent component. And also expects change handlers - actions - passed as props to the component.

This all works because when validation is called your component defines what data to validate - in FLUX your data is given to your component from a container that has direct connection to the backing stores. So you give props as the source of validation data:

getValidatorData() {
    return this.props;
  }

Workflow

If you need to validate certain fields outside of this validation library, then do the following:

You could also write a custom validation strategy that can do everything you need.

Example

Isolate the fields you will validate with this library:

getValidatorData() {
    const { username, password } = this.props;
   return {
    username,
    password
  };
}

For the remaining fields that you need to validate in some custom way, use actions - passed as props - to handle the validation. Below we have our birthdate field value, validity, and change handler all coming from props. Essentially the change handler, this.props.handleBirthdateChange will allow you to fire an action to update your store and validate the field. And the this.props.isBirthdateValid property will allow you to know how to style your form.

<div className={this.props.isBirthdateValid ? 'has-error' : ''}>
  <input type='text'
           className='form-control'
           placeholder='mm/dd/yyyy'
           value={this.props.birthdate}
           onChange={this.props.handleBirthdateChange}
           />
</div>

And when validating ensure you account for the extra validations if (error || !this.props.isBirthdateValid)...:

  onSubmit(event) {
    event.preventDefault();
    const onValidate = error => {
      if (error || !this.props.isBirthdateValid) {
        //form has errors; do not submit
      } else {
        this.props.submitForm();
      }
    };
    this.props.validate(onValidate);
  }

Let me know if you need more info. I think the cleanest way to solve this is to use a custom validation strategy, but the above will work as well.

pdolega commented 8 years ago

@jurassix can't tell you have much grateful I am for your quick reply (which cannot be said by mine response now - picking up on this thread after nearly 2 weeks). And all of this for issue that should rather be question on mailing list... Thanks !

Just trying to apply what you wrote. Will let know how it went.