React: input validation

送分小仙女□ 提交于 2020-01-02 04:15:08

问题


I recently started working with React and I faced the problem with inputs validation. For example, it simply implemented in another framework as Angular.js via directives.

After some researching I found

  1. newforms library, looks like the best solution from the box on current moment. But it's pretty heavy and not sure that it's currently supported (last update 7 months ago).
  2. Another approach is sending events from parent form to its children inputs, and calling validation method on each.

But I could not find the best practices everyone tries to invent something own and as a result you need to write something own.

What is best solution for form validation? Does React architecture/frameworks (Flux/Redux) provide any solution?

Thanks,


回答1:


I worked with some forms in React recently, and I had a very similar experience. I think what this boils down to is that React is very new, and form validation is a hard problem to solve in general. This leads to kind of a Wild West of form validation, where there is no set standards, and many new libraries trying to solve the problem (each doing it their own way and making lots of assumptions).

I ended up using formsy-react (https://github.com/christianalfoni/formsy-react) which was fairly straight-forward, but made one big assumption - that we want to validate the input onChange. I wanted my inputs to render an error onBlur which lead to me writing some helper functions to create that behavior.

I haven't yet dug into Redux too much, but there do seem to be some good options in that arena (https://www.npmjs.com/package/redux-form), that may suit your needs.

Let me know if you'd like to see an example of my Formsy form validators/helper methods.

Hope this helped, or at least provided some solidarity that form validation in the React world is, as of now, unclear and lacks a standard.




回答2:


I am using light weigh solution and it's pretty customizable.

The input validated on onChange but can be changed on any. We can create similar component for textarea, checkbox, radio

var Input = React.createClass({
  getInitialState: function(){
    // we don't want to validate the input until the user starts typing
    return {
      validationStarted: false
    };
  },
  prepareToValidate: function(){},
  _debounce: function(func, wait, immediate) {
    var timeout;
    return function() {
      var context = this, args = arguments;
      var later = function() {
        timeout = null;
        if (!immediate) func.apply(context, args);
      };
      var callNow = immediate && !timeout;
      clearTimeout(timeout);
      timeout = setTimeout(later, wait);
      if (callNow) func.apply(context, args);
    };
  },
  componentWillMount: function(){
    var startValidation = function(){
      this.setState({
        validationStarted: true
      })
    }.bind(this);

    // if non-blank value: validate now
    if (this.props.value) {
      startValidation();
    }
    // wait until they start typing, and then stop
    else {
      this.prepareToValidate = _self._debounce(startValidation, 1000);
    }
  },
  handleChange: function(e){
    if (!this.state.validationStarted) {
      this.prepareToValidate();
    }
    this.props.onChange && this.props.onChange(e);
  },
  render: function(){
    var className = "";
    if (this.state.validationStarted) {
      className = (this.props.valid ? 'Valid' : 'Invalid');
    }
    return (
      <input
        {...this.props}
        className={className}
        onChange={this.handleChange} />
    );
  }
});

Our component where we are going to render the form. We can add as many validation rules as want

var App = React.createClass({
  getInitialState: function(){
    return {email: ""};
  },
  handleChange: function(e){
    this.setState({
      email: e.target.value
    })
  },
  validate: function(state){
    return {
      email: /^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/.test(state.email)
    }
  },
  render: function(){
    var valid = this.validate(this.state);
    return (
      <div>
        <Input valid={valid.email}
               value={this.state.email} 
               onChange={this.handleChange} 
               placeholder="example@example.com"/>
      </div>
    );
  }
});

This is pretty simple and customizable and for small projects work very good. But if we a project large and has a lot of different form, to write every time App component with handlers is not best choice



来源:https://stackoverflow.com/questions/32791463/react-input-validation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!