react 组件封装原则_React Form组件的实现封装杂谈

React Form组件的实现封装杂谈

发布时间:2019-01-08 发布网站:编程之家

编程之家收集整理的这篇文章主要介绍了React Form组件的实现封装杂谈,编程之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

前言

对于网页系统来说,表单提交是一种很常见的与用户交互的方式,比如提交订单的时候,需要输入收件人、手机号、地址等信息,又或者对系统进行设置的时候,需要填写一些个人偏好的信息。 表单提交是一种结构化的操作,可以通过封装一些通用的功能达到简化开发的目的。本文将讨论Form表单组件设计的思路,并结合有赞的ZentForm组件介绍具体的实现方式。本文所涉及的代码都是基于React v15的版本。

Form组件功能

一般来说,Form组件的功能包括以下几点:

表单布局

表单字段

封装表单验证&错误提示

表单提交

下面将对每个部分的实现方式做详细介绍。

表单布局

常用的表单布局一般有3种方式:

行内布局

水平布局

垂直布局

实现方式比较简单,嵌套css就行。比如form的结构是这样:

对应3种布局,只需要在form标签增加对应的class:

相应的,要定义3种布局的css:

.horizontal .label {

display: inline-block;

...

}

.horizontal .field {

display: inline-block;

...

}

.vertical .label {

display: block;

...

}

.vertical .field {

display: block;

...

}

表单字段封装

字段封装部分一般是对组件库的组件针对Form再做一层封装,如Input组件、Select组件、Checkbox组件等。当现有的字段不能满足需求时,可以自定义字段。

表单的字段一般包括两部分,一部分是标题,另一部分是内容。ZentForm通过getControlGroup这一高阶函数对结构和样式做了一些封装,它的入参是要显示的组件:

{

render() {

return (

: null}

{label}

{showError && (

)}

{notice &&

}

{helpDesc &&

}

);

}

}

这里用到的label和error等信息,是通过Field组件传入的:

这里的CustomizedComp是通过getControlGroup封装后返回的组件。

字段与表单之间的交互是一个需要考虑的问题,表单需要知道它包含的字段值,需要在适当的时机对字段进行校验。ZentForm的实现方式是在Form的高阶组件内维护一个字段数组,数组内容是Field的实例。后续通过操作这些实例的方法来达到取值和校验的目的。

ZentForm的使用方式如下:

)

}

}

export default createForm()(FieldForm);

其中Form和Field是组件库提供的组件,CustomizedComp是自定义的组件,createForm是组件库提供的高阶函数。在createForm返回的组件中,维护了一个fields的数组,同时提供了attachToForm和detachFromForm两个方法,来操作这个数组。这两个方法保存在context对象当中,Field就能在加载和卸载的时候调用了。简化后的代码如下:

{

...

return WrappedForm => {

return class Form extends Component {

constructor(props) {

super(props);

this.fields = [];

}

getChildContext() {

return {

zentForm: {

attachToForm: this.attachToForm,detachFromForm: this.detachFromForm,}

}

}

attachToForm = field => {

if (this.fields.indexOf(field) < 0) {

this.fields.push(field);

}

};

detachFromForm = field => {

const fieldPos = this.fields.indexOf(field);

if (fieldPos >= 0) {

this.fields.splice(fieldPos,1);

}

};

render() {

return createElement(WrappedForm,{...});

}

}

}

}

/**

Field组件

*/

class Field extends Component {

componentWillMount() {

this.context.zentForm.attachToForm(this);

}

componentWillUnmount() {

this.context.zentForm.detachFromForm(this);

}

render() {

const { component } = this.props;

return createElement(component,{...});

}

}

当需要获取表单字段值的时候,只需要遍历fields数组,再调用Field实例的相应方法就可以:

{

...

return WrappedForm => {

return class Form extends Component {

getFormValues = () => {

return this.fields.reduce((values,field) => {

const name = field.getName();

const fieldValue = field.getValue();

values[name] = fieldValue;

return values;

},{});

};

}

}

}

/**

* Field组件

*/

class Field extends Component {

getValue = () => {

return this.state._value;

};

}

表单验证&错误提示

表单验证是一个重头戏,只有验证通过了才能提交表单。验证的时机也有多种,如字段变更时、鼠标移出时和表单提交时。ZentForm提供了一些常用的验证规则,如非空验证,长度验证,邮箱地址验证等。当然还能自定义一些更复杂的验证方式。自定义验证方法可以通过两种方式传入ZentForm,一种是通过给createForm传参:

另一种方式是给Field组件传属性:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值