@achingbrain/react-validation 中文文档教程

发布于 7年前 浏览 15 项目主页 更新于 3年前

react-validation

npm 版本构建状态覆盖状态dependenciesdevDependencies

为 React 组件提供简单表单验证的组件。 它使用受控组件方法进行验证。

使用 React 验证表单并不容易。 原因是单向数据流风格。 在这种情况下,我们不能以简单的方式影响来自输入的表单。 React-validation 提供了几个组件,这些组件通过 Form 组件附加的输入方法“连接”到表单。

DEMO

DEMO src

它只是一个验证,不提供任何模型或类似的东西。 您可以使用 FormData 或类似 form-serialize 的东西来获取表单数据。

NOTE: Always pass the name and validations props. They are required.

Validation.Form 标记内允许附加标记。

任何额外的道具(例如事件处理程序)也可以传递给组件。

如果您发现任何错误或错误,请随时提出问题。 也欢迎请求请求。

Installation

<代码> npm 安装反应验证

Test

<代码> npm 运行测试:开发

Example usage

使用@2.*,react-validation 不再依赖于外部validator。 您可以通过扩展 rules 对象来使用您想要的任何验证策略。 让我们看一下它的初始状态:

export default = {};

就是这样,只是一个空的对象字面量。 由于可能性极高,我们没有任何验证规则 OOTB,但出于已知原因,仍建议使用经过良好测试的库。

所以首先让我们扩展它并添加一些规则:

import React from 'react';
// NOTE: Deprecated
import Validation from 'react-validation';
// From v2.10.0
// import { rules, Form, Input, Select, Textarea, Button } from 'react-validation/lib/build/validation.rc'
import validator from 'validator';

// Use Object.assign or any similar API to merge a rules
// NOTE: IE10 doesn't have Object.assign API natively. Use polyfill/babel plugin.
Object.assign(Validation.rules, {
    // Key name maps the rule
    required: {
        // Function to validate value
        // NOTE: value might be a number -> force to string
        rule: value => {
            return value.toString().trim();
        },
        // Function to return hint
        // You may use current value to inject it in some way to the hint
        hint: value => {
            return <span className='form-error is-visible'>Required</span>
        }
    },
    email: {
        // Example usage with external 'validator'
        rule: value => {
            return validator.isEmail(value);
        },
        hint: value => {
            return <span className='form-error is-visible'>{value} isnt an Email.</span>
        }
    },
    // This example shows a way to handle common task - compare two fields for equality
    password: {
        // rule function can accept argument:
        // components - components registered to Form mapped by name
        rule: (value, components) => {
            const password = components.password.state;
            const passwordConfirm = components.passwordConfirm.state;
            const isBothUsed = password
                && passwordConfirm
                && password.isUsed
                && passwordConfirm.isUsed;
            const isBothChanged = isBothUsed && password.isChanged && passwordConfirm.isChanged;

            if (!isBothUsed || !isBothChanged) {
                return true;
            }

            return password.value === passwordConfirm.value;
        },
        hint: () => <span className="form-error is-visible">Passwords should be equal.</span>
    },
    // Define API rule to show hint after API error response
    api: {
        // We don't need the rule here because we will call the 'showError' method by hand on API error
        hint: value => (
            <button
                className="form-error is-visible"
            >
                API Error on "{value}" value. Focus to hide.
            </button>
        )
    }
});

现在我们已经将 requiredemail 添加到我们的规则中,并提供提示。 这可能会在注册了所有规则的文件中分开。

就是这样。 我们现在可以在我们的 React 组件中使用它:

import Validation from 'react-validation';
import React, {Component, PropTypes} from 'react';

export default class Registration extends Component {
    render() {
        return <Validation.components.Form>
            <h3>Registration</h3>
            <div>
                <label>
                    Email*
                    <Validation.components.Input value='email@email.com' name='email' validations={['required', 'email']}/>
                </label>
            </div>
            <div>
                <label>
                    Password*
                    <Validation.components.Input type='password' value='' name='password' validations={['required']}/>
                </label>
            </div>
            <div>
                <Validation.components.Button>Submit</Validation.components.Button>
            </div>
        </Validation.components.Form>;
    }
}

注意 validations 属性。 它是一个字符串数组,映射到我们扩展的规则键。

Components and props

react-validation提供了一个components对象,包含FormInputSelectTextareaButton 组件。 所有这些都只是原生组件的自定义包装器。 他们可以接受任何有效的属性和一些额外的:

  1. containerClassName - Input, Select and Textarea: react-validation wraps the native components with an extra block. This prop adds a className to the wrapper.
  2. errorContainerClassName: wrapper's error modifier className.
  3. validations - Input, Select and Textarea: accepts an array of validations strings that refers to the rules object's keys.
  4. errorClassName - Input, Select, Button and Textarea: adds the passed value to className on error occurrences.
NOTE: Always provide a name prop to Input, Select and Textarea. Always pass the validations prop to Input, Select and Textarea.

Form component

Validation.components.Form

最重要的组件,它提供了反应验证的核心。 它基本上通过 context 混合了表单本身和子 react-validation 组件之间的绑定。 任何有效的道具都可以很容易地传递给 Form,例如 onSubmitmethod

Form 提供四种公共方法:

  1. validate(name) - 使用传递的名称验证输入。 此方法与默认验证的区别在于 validate 将输入标记为 isUsedisChangedname - 相应组件的名称。

  2. showError(name [,hint]) - 帮助处理异步 API 错误。 hint - 要显示的可选提示。 可以是字符串(错误键,ex 'required')或返回提示的函数(jsx)。

  3. hideError(name) - 隐藏相应组件的错误。

  4. validateAll() - 验证所有反应验证组件。 返回无效字段的映射(键:字段名称 prop,值: 未通过验证规则)。

export default class Comment extends Component {
    handleSubmit = (event) => {
        event.preventDefault();

        // Emulate async API call
        setTimeout(() => {
            // NOTE: 'api' should be defined on 'extend' step
            this.form.showError('username', 'api');
        }, 1000);
    };

    removeApiError = () => {
        this.form.hideError('username');
    };

    render() {
        return <Validation.components.Form ref={c => { this.form = c }} onSubmit={this.handleSubmit.bind(this)}>
            <div className="row">
                <div className="small-12 columns">
                    <h3>Leave a comment</h3>
                </div>
            </div>
            <div className="row">
                <div className="small-12 medium-4 columns">
                    <label>
                        <Validation.components.Input
                          onFocus={this.removeApiError}
                          placeholder="username"
                          type="text"
                          errorClassName="is-invalid-input"
                          containerClassName=""
                          value="Username"
                          name="username"
                          validations={['required', 'alpha']}
                        />
                    </label>
                </div>
                <div className="small-12 medium-8 columns">
                    <label>
                        <Validation.components.Textarea
                          placeholder="Leave your comment..."
                          errorClassName="is-invalid-input"
                          containerClassName=""
                          value="Comment"
                          name="comment"
                          validations={['required']}
                        />
                    </label>
                </div>
            </div>
            <div className="row">
                <div className="small-12 medium-6 columns">
                    <Validation.components.Button className="button">Submit</Validation.components.Button>
                </div>
            </div>
        </Validation.components.Form>
    }
}

Input component

Validation.components.Input

原生 input 的包装器。 它接受一个 validations 属性——一个引用规则对象键的字符串数组。

<Validation.components.Input name='firstname' validations={['alpha', 'lt8']}/>
NOTE: For types radio and checkbox, react-validation will drop the value to an empty string when it's not checked. This is to avoid validation of non-checked inputs.

react-validation 将打破第一个列出的规则,如果违反了多个规则。 在上面的示例中(lt8 - 值长度小于 8),对于 d1g1t 的非常长的值 输入值,alpha 规则将首先中断验证。 我们可以通过在 validations 数组中排序规则来控制它。

Textarea component

Validation.components.Textarea

原生 textarea 的包装器。 与 Input 一样,它接受 validations 属性。 这里没什么特别的:

<Validation.components.Textarea name='comment' value='' validations={['required']}/>

Select component

Validation.components.Select

原生 select 的包装器。 与 Input 一样,它接受 validations 属性。 这里没什么特别的:

<Validation.components.Select name='city' value='' validations={['required']}>
    <option value=''>Choose your city</option>
    <option value='1'>London</option>
    <option value='2'>Kyiv</option>
    <option value='3'>New York</option>
</Validation.components.Select>

Button component

Validation.components.Button

原生 button 的包装器。 React-validation 在发生错误时禁用(添加 disabled 属性)按钮。 可以通过将 disabled 属性直接传递给组件来抑制此行为。

Custom components

如果 react-validation 提供的组件不能完全满足您对标记结构的需求(例如,您 可能希望 hint 之前显示),您可以创建自己的版本 inputselecttextarea。 (buttonform 是简单的单元素 组件,不需要进一步定制)。

这是一个根据 Bootstrap 呈现 的示例 CSS 框架:

import React, { Component } from 'react';
import { inputFactory } from 'react-validation/lib/build/validation.rc';

// Not using ES6 classes? Then you'd write instead:
// const MyBootstrapInput = React.createClass(...)
//
// If you are using ES7 decorators, you can use:
// @inputFactory
class MyBootstrapInput extends Component {
    render() {
        return (
            <div className={`form-group ${this.props.hint && 'has-error'} ${this.props.containerClassName}`}>
                <label className="control-label" htmlFor={this.props.id}>
                    {this.props.label}{/* You can use your own props */}
                </label>
                {/* "onChange", "onBlur", and "value/checked" are important, don't forget them: */}
                <input
                    className={`form-control ${this.props.className}`}
                    id={this.props.id}
                    type={this.props.type}

                    onChange={this.props.onChange}
                    onBlur={this.props.onBlur}
                    value={this.props.value}
                    checked={this.props.checked}
                />
                { this.props.hint && <div className="help-block">{this.props.hint}</div> }
            </div>
        );
    }
}

// Wrap the component in the factory (if not using ES7 decorators)
export default inputFactory(MyBootstrapInput);

然后您可以像使用其他反应验证组件一样使用自定义组件:

import BootstrapInput from 'path/to/my/component/file';

<BootstrapInput label="Email" value='email@email.com' name='email' validations={['required', 'email']}/>

Migration from 1.*

extendErrors API

extendErrors 不再存在。 将其替换为验证规则注册的新方法。 hint 外观现在完全受控:

Object.assign(Validation.rules, {
    required: {
        rule: value => {
            return value.trim();
        },
        hint: value => {
            return <span className='form-error is-visible'>Required</span>
        }
    }
});

Defaults

React-validation 不再有任何默认值。 这是 TBD,但对于 2.0.0,请直接向验证组件提供 errorClassNamecontainerClassName

Validations

validations 属性现在接受字符串数组而不是对象。 它变得更加简单并减少了 render 代码。

组件 API 移至表单 API。 forceValidate 方法不再存在。

react-validation

npm versionBuild StatusCoverage StatusdependenciesdevDependencies

Component to provide simple form validation for React components. It uses the Controlled Components approach for validation.

It is not easy to validate forms with React. The reason is a one-way data flow style. In this case we can't affect forms from the inputs in an easy way. React-validation provides several components which are 'connected' to the form via the input's method attached by the Form component.

DEMO

DEMO src

It is just a validation and doesn't provide any model or something similar. You can use FormData or something like form-serialize to get form data.

NOTE: Always pass the name and validations props. They are required.

Additional markup is allowed inside the Validation.Form markup.

Any additional props (such as event handlers) can also be passed to components.

If you find any bug or error, please feel free to raise an issue. Pull requests are also welcome.

Installation

npm install react-validation

Test

npm run test:dev

Example usage

With @2.*, react-validation is no longer dependent on the external validator. You may use whatever validation strategy you want by extending the rules object. Let's take a look at its initial state:

export default = {};

That's it, just an empty object literal. We don't have any validation rules OOTB because of an extremely high number of possibilities, but it's still recommended to use a well-tested library for known reasons.

So first of all let's extend it and add some rules:

import React from 'react';
// NOTE: Deprecated
import Validation from 'react-validation';
// From v2.10.0
// import { rules, Form, Input, Select, Textarea, Button } from 'react-validation/lib/build/validation.rc'
import validator from 'validator';

// Use Object.assign or any similar API to merge a rules
// NOTE: IE10 doesn't have Object.assign API natively. Use polyfill/babel plugin.
Object.assign(Validation.rules, {
    // Key name maps the rule
    required: {
        // Function to validate value
        // NOTE: value might be a number -> force to string
        rule: value => {
            return value.toString().trim();
        },
        // Function to return hint
        // You may use current value to inject it in some way to the hint
        hint: value => {
            return <span className='form-error is-visible'>Required</span>
        }
    },
    email: {
        // Example usage with external 'validator'
        rule: value => {
            return validator.isEmail(value);
        },
        hint: value => {
            return <span className='form-error is-visible'>{value} isnt an Email.</span>
        }
    },
    // This example shows a way to handle common task - compare two fields for equality
    password: {
        // rule function can accept argument:
        // components - components registered to Form mapped by name
        rule: (value, components) => {
            const password = components.password.state;
            const passwordConfirm = components.passwordConfirm.state;
            const isBothUsed = password
                && passwordConfirm
                && password.isUsed
                && passwordConfirm.isUsed;
            const isBothChanged = isBothUsed && password.isChanged && passwordConfirm.isChanged;

            if (!isBothUsed || !isBothChanged) {
                return true;
            }

            return password.value === passwordConfirm.value;
        },
        hint: () => <span className="form-error is-visible">Passwords should be equal.</span>
    },
    // Define API rule to show hint after API error response
    api: {
        // We don't need the rule here because we will call the 'showError' method by hand on API error
        hint: value => (
            <button
                className="form-error is-visible"
            >
                API Error on "{value}" value. Focus to hide.
            </button>
        )
    }
});

Now we've added required and email to our rules with provided hints. This might be separated in a file where all the rules are registered.

That's it. We can now use it in our React components:

import Validation from 'react-validation';
import React, {Component, PropTypes} from 'react';

export default class Registration extends Component {
    render() {
        return <Validation.components.Form>
            <h3>Registration</h3>
            <div>
                <label>
                    Email*
                    <Validation.components.Input value='email@email.com' name='email' validations={['required', 'email']}/>
                </label>
            </div>
            <div>
                <label>
                    Password*
                    <Validation.components.Input type='password' value='' name='password' validations={['required']}/>
                </label>
            </div>
            <div>
                <Validation.components.Button>Submit</Validation.components.Button>
            </div>
        </Validation.components.Form>;
    }
}

Note the validations prop. It's an array of strings that maps to the rules keys we've extended.

Components and props

react-validation provides a components object that contains Form, Input, Select, Textarea and Button components. All of them are just custom wrappers around the native components. They can accept any valid attributes and a few extra:

  1. containerClassName - Input, Select and Textarea: react-validation wraps the native components with an extra block. This prop adds a className to the wrapper.
  2. errorContainerClassName: wrapper's error modifier className.
  3. validations - Input, Select and Textarea: accepts an array of validations strings that refers to the rules object's keys.
  4. errorClassName - Input, Select, Button and Textarea: adds the passed value to className on error occurrences.
NOTE: Always provide a name prop to Input, Select and Textarea. Always pass the validations prop to Input, Select and Textarea.

Form component

Validation.components.Form

The most important component, which provides the heart of react-validation. It basically mixes the binding between the form itself and child react-validation components via context. Any valid props can easily be passed to Form, such onSubmit and method.

Form provides four public methods:

  1. validate(name) - validates input with the passed name. The difference between this method and default validation is that validate marks the input as isUsed and isChanged. name - name of the corresponding component.

  2. showError(name [,hint]) - helps to handle async API errors. hint - optional hint to show. Can be string (error key, ex 'required') or function which returns hint (jsx).

  3. hideError(name) - hides a corresponding component's error.

  4. validateAll() - validates all react-validation components. Returns a map (key: field name prop, value: <Array> non passed validation rules) of invalid fields.

export default class Comment extends Component {
    handleSubmit = (event) => {
        event.preventDefault();

        // Emulate async API call
        setTimeout(() => {
            // NOTE: 'api' should be defined on 'extend' step
            this.form.showError('username', 'api');
        }, 1000);
    };

    removeApiError = () => {
        this.form.hideError('username');
    };

    render() {
        return <Validation.components.Form ref={c => { this.form = c }} onSubmit={this.handleSubmit.bind(this)}>
            <div className="row">
                <div className="small-12 columns">
                    <h3>Leave a comment</h3>
                </div>
            </div>
            <div className="row">
                <div className="small-12 medium-4 columns">
                    <label>
                        <Validation.components.Input
                          onFocus={this.removeApiError}
                          placeholder="username"
                          type="text"
                          errorClassName="is-invalid-input"
                          containerClassName=""
                          value="Username"
                          name="username"
                          validations={['required', 'alpha']}
                        />
                    </label>
                </div>
                <div className="small-12 medium-8 columns">
                    <label>
                        <Validation.components.Textarea
                          placeholder="Leave your comment..."
                          errorClassName="is-invalid-input"
                          containerClassName=""
                          value="Comment"
                          name="comment"
                          validations={['required']}
                        />
                    </label>
                </div>
            </div>
            <div className="row">
                <div className="small-12 medium-6 columns">
                    <Validation.components.Button className="button">Submit</Validation.components.Button>
                </div>
            </div>
        </Validation.components.Form>
    }
}

Input component

Validation.components.Input

A wrapper around the native input. It accepts a validations prop - an array of strings that refers to rules object keys.

<Validation.components.Input name='firstname' validations={['alpha', 'lt8']}/>
NOTE: For types radio and checkbox, react-validation will drop the value to an empty string when it's not checked. This is to avoid validation of non-checked inputs.

react-validation will break with the first listed rule, if more than one rule is broken. In the example above (lt8 - value length less than 8), for really long value with d1g1t input value, the alpha rule will break validation first. We can control it by ordering rules within the validations array.

Textarea component

Validation.components.Textarea

A wrapper around the native textarea. Like Input, it accepts a validations prop. Nothing special here:

<Validation.components.Textarea name='comment' value='' validations={['required']}/>

Select component

Validation.components.Select

A wrapper around the native select. Like Input, it accepts a validations prop. Nothing special here:

<Validation.components.Select name='city' value='' validations={['required']}>
    <option value=''>Choose your city</option>
    <option value='1'>London</option>
    <option value='2'>Kyiv</option>
    <option value='3'>New York</option>
</Validation.components.Select>

Button component

Validation.components.Button

A wrapper around the native button. React-validation disables (adds disabled prop) the button on error occurrences. This behavior could be suppressed by passing the disabled prop directly to a component.

Custom components

If the components provided by react-validation don't quite fit your needs for markup structure (for instance, you might want the hint to show before an <input>), you can create your own versions of input, select, and textarea. (button and form are simple single-element components, and shouldn't need further customisation).

Here is an example that would render an <input> according to the Bootstrap CSS framework:

import React, { Component } from 'react';
import { inputFactory } from 'react-validation/lib/build/validation.rc';

// Not using ES6 classes? Then you'd write instead:
// const MyBootstrapInput = React.createClass(...)
//
// If you are using ES7 decorators, you can use:
// @inputFactory
class MyBootstrapInput extends Component {
    render() {
        return (
            <div className={`form-group ${this.props.hint && 'has-error'} ${this.props.containerClassName}`}>
                <label className="control-label" htmlFor={this.props.id}>
                    {this.props.label}{/* You can use your own props */}
                </label>
                {/* "onChange", "onBlur", and "value/checked" are important, don't forget them: */}
                <input
                    className={`form-control ${this.props.className}`}
                    id={this.props.id}
                    type={this.props.type}

                    onChange={this.props.onChange}
                    onBlur={this.props.onBlur}
                    value={this.props.value}
                    checked={this.props.checked}
                />
                { this.props.hint && <div className="help-block">{this.props.hint}</div> }
            </div>
        );
    }
}

// Wrap the component in the factory (if not using ES7 decorators)
export default inputFactory(MyBootstrapInput);

You can then use your custom component like the other react-validation components:

import BootstrapInput from 'path/to/my/component/file';

<BootstrapInput label="Email" value='email@email.com' name='email' validations={['required', 'email']}/>

Migration from 1.*

extendErrors API

extendErrors no longer exists. Replace it with the new approach of validation rules registration. hint appearance is now fully controlled:

Object.assign(Validation.rules, {
    required: {
        rule: value => {
            return value.trim();
        },
        hint: value => {
            return <span className='form-error is-visible'>Required</span>
        }
    }
});

Defaults

React-validation no longer has any defaults. This is TBD but for a 2.0.0 please provide errorClassName and containerClassName directly to the validation components.

Validations

validations prop now accepts an array of strings instead of objects. It's made to be more simple and reduce render code.

Components API moved to Form API. forceValidate method no longer exist.

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文