Реакция: проверка ввода

Недавно я начал работать с React и столкнулся с проблемой проверки входных данных. Например, он просто реализован в другом фреймворке как Angular.js через директивы.

После некоторых исследований я нашел

  1. newforms выглядит как лучшее решение из коробки на текущем момент. Но он довольно тяжелый и не уверен, что он в настоящее время поддерживается (последнее обновление 7 месяцев назад).
  2. Другой подход заключается в отправке событий из родительской формы в ее дочерние входы и вызове метода проверки для каждого.

Но лучших практик найти не смог, все пытаются придумать что-то свое и в итоге нужно писать что-то свое.

Какое лучшее решение для проверки формы? Предоставляет ли архитектура/фреймворки React (Flux/Redux) какое-либо решение?

Спасибо,


person Vladyslav Babenko    schedule 25.09.2015    source источник


Ответы (2)


Недавно я работал с некоторыми формами в React, и у меня был очень похожий опыт. Я думаю, что это сводится к тому, что React очень нов, и проверка формы — это сложная проблема для решения в целом. Это приводит к своего рода Дикому Западу проверки формы, где нет установленных стандартов, и множество новых библиотек пытаются решить проблему (каждая делает это по-своему и делает множество предположений).

В итоге я использовал formsy-react (https://github.com/christianalfoni/formsy-react ), что было довольно прямолинейно, но содержало одно большое предположение — мы хотим проверить входные данные onChange. Я хотел, чтобы мои входные данные отображали ошибку onBlur, что привело к написанию некоторых вспомогательных функций для создания такого поведения.

Я еще не слишком много копался в Redux, но, похоже, в этой области есть несколько хороших вариантов (https://www.npmjs.com/package/redux-form), который может удовлетворить ваши потребности.

Дайте мне знать, если вы хотите увидеть пример моих валидаторов/вспомогательных методов формы Formsy.

Надеюсь, это помогло или, по крайней мере, обеспечило некоторую солидарность с тем, что проверка формы в мире React на данный момент неясна и не имеет стандарта.

person camerow    schedule 30.09.2015

Я использую легкое решение, и оно довольно настраиваемое.

Ввод проверен onChange, но может быть изменен в любое время. Мы можем создать аналогичный компонент для 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} />
    );
  }
});

Наш компонент, в котором мы собираемся отображать форму. Мы можем добавить столько правил проверки, сколько захотим

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="[email protected]"/>
      </div>
    );
  }
});

Это довольно просто и настраивается, и для небольших проектов работает очень хорошо. Но если у нас проект большой и имеет много разных форм, каждый раз писать компонент приложения с обработчиками — не лучший выбор.

person Vladyslav Babenko    schedule 01.10.2015