jurassix / react-validation-mixin

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

Added param "component", containing getValidatorData function, to… #57

Closed 40818419 closed 5 years ago

40818419 commented 8 years ago

…handleValidation. Added linting params.

Example of Alt + Flux (http://alt.js.org) + React Bootstrap:

import React from 'react';
import {Input} from 'react-bootstrap';

import Joi from 'joi';
import validation from 'react-validation-mixin';
import strategy from 'joi-validation-strategy';

import connectToStores from 'alt/utils/connectToStores';
import ...Actions from '../../actions/...Actions';
import ...Store from '../../stores/...Store';

class SomeComponent extends React.Component {
  constructor(props){
    super(props);
    this.validatorTypes = {
      identifier: Joi.string().required().email().label('Email address')
    }
    this.state = {
      ...
    }
  }
  static getStores() {
    return [...]
  }
  static getPropsFromStores() {
    return {
      ...
    }
  }
  getValidatorData() {
    return this.state;
  }
  onSubmit(e){
    ...
  }
  onChange(field) {
    ...
  }
  render() {
    return (
        <form onSubmit={this.onSubmit} noValidate>
          <Input
            defaultValue={this.state.email}
            type="email"
            ref="email"
            className="form-control"
            placeholder="Email address"
            help={ this.props.getValidationMessages('email') }
            bsStyle={ this.props.isValid('email') ? '' : 'error' }
            onBlur={ this.props.handleValidation('email', null, this) }
            onChange={(event) => {
              this.onChange({
                name: 'email',
                value: event.target.value
              });
            }} />
            <button
              disabled={ !this.props.isValid() }
              className="btn btn-lg btn-primary btn-block">
              Sign in
            </button>
          </form>
        )
      }
    }

    export default validation(strategy)(connectToStores(SomeComponent));
jurassix commented 8 years ago

Hi! Thanks for the PR.

I'm a little confused by the additional component param. We already have a ref to the component, this.refs.component, that will allows us access to getValidatorData.

Can you provide a little more information about the problem you are solving?

40818419 commented 8 years ago

hey, this.refs.component is giving me Constructor because it's wrapped into connectToStores, and we need to access SomeComponent. Is there any possibility to pass the scope?

jurassix commented 8 years ago

Ah. Thanks for the clarity. Let me think about the best approach.

I'm assuming that swapping the composition ordering also fails?

export default connectToStores(validation(strategy)(SomeComponent))

40818419 commented 8 years ago

yes, those methods are required:

  static getStores() {
    return [...]
  }
  static getPropsFromStores() {
    return {
      ...
    }
  }

Thanx!

idolize commented 8 years ago

@40818419 I'd recommend using this approach to define your static methods on the finalized HOC rather than trying to access them on the wrapped component.

jurassix commented 8 years ago

@40818419 I agree with @idolize here. Wrapping your component in another HOC on export that simply adds the statics to the outer component is the recommended solution.

If you need code samples for this, I can help too.

I would like to merge in your .eslintrc changes. Can you update this PR with just those?

idolize commented 8 years ago

@jurassix Actually, in the example linked, the statics decorator does not create another HOC (just simply adds the static methods to the existing HOC), but either way works :smile:

jurassix commented 8 years ago

@idolize Yeah adding directly to outer component does seems better. I've done some perf tests on HOC in the past and the deeper you go the more processing time is required each render.

40818419 commented 8 years ago

@jurassix how this will look like than? will update PR.

jurassix commented 8 years ago

@40818419 Try this:

const component = validation(strategy)(connectToStores(SomeComponent))
component.getStores() {
  return [...]
}
component.getPropsFromStores() {
  return {
    ...
  }
}
export default component;
jurassix commented 8 years ago

@40818419 Or this: just depends on your syntax preference

const component = validation(strategy)(connectToStores(SomeComponent))
Object.assign(component, {
  getStores() {
    return [...]
  },
  getPropsFromStores() {
    return {
      ...
    }
  }
});
export default component;
jurassix commented 8 years ago

@40818419 did this work for you?

40818419 commented 8 years ago

@jurassix unfortunately not, need more time...

jurassix commented 5 years ago

closing due to inactivity.