前言
在平日业务开发中,为了节省时间,可能大部分程序员都是习惯性的打开antd
官网,选择组件,展开copy就完事,过后可能很少去理解怎么实现的,比如我们常用的Form表单,怎么用input标签实现数据的数据的搜集,报错的显示,以及实现的设计模式等。
小知识
什么是高阶组件-HOC? 为了提高组件复用率,可测试性,就要保证组件功能单一性;但是诺要满足复杂需求就要扩展功能单一的组件,所以在React⾥就有了 HOC(Higher-Order Components)的概念。简单的说就是参数为组件,返回值为新组件的函数
简单例子
// HocPage.js
import React, {Component} from "react";
// hoc: 是⼀个函数,接收⼀个组件,返回另外⼀个组件
//这⾥⼤写开头的Cmp是指function或者class组件
const foo = Cmp => props => {
return (
<div className="border">
<Cmp {...props} />
</div>
);
};
function Child(props) {
return <div> Child {props.name}</div>;
}
const Foo = foo(Child);
export default class HocPage extends Component {
render() {
return (
<div>
<h3>HocPage</h3>
<Foo name="msg" />
</div>
);
}
}
表单组件设计思路
- 表单组件要求实数据收集、校验、提交等特性,可通过高级组件扩展
- 高阶组件给表单组件传递一个input组件包装函数接管其输入事件并统一管理表单数据
- 高阶组件给表单组件传递一个校验函数使其具备数据校验功能
组件实现
- 表单基本结构,创建MyFormPage.js
import React, { Component } from "react";
import MyFormCreate from "../conponents/MyFormCreate";
//校验规则
const nameRules = { required: true, message: "please input ur name"};
const passwordRules = { required: true, message: "please input ur password"};
export default MyFormCreate(
class MyFormPage extends Component {
submit = () => {
const { getFieldsValue, getFieldValue, validateFields } = this.props;
validateFields((err, values) => {
if (err) {
console.log("err", err);
} else {
console.log("success", values);
}
});
getFieldValue("name");
};
render() {
const { getFieldDecorator } = this.props;
return (
<div>
<h3>MyFormPage</h3>
{getFieldDecorator("name", { rules: [nameRules] })(
<input type="text" placeholder="please input ur name" />
)}
{getFieldDecorator("password", { rules: [passwordRules] })(
<input type="password" placeholder="please input ur password" />
)}
<button onClick={this.submit}>提交</button>
</div>
);
}
}
);
- 高阶组件MyFormCreate扩展现有表单,./components/MyFormCreate.js
import React, { Component } from "react";
export default function MyFormCreate(Cmp) {
return class extends Component {
constructor(props) {
super(props);
this.state = {};
this.options = {};
}
handleChange = (e) => {
let { name, value } = e.target;
this.setState({ [name]: value });
};
getFieldDecorator = (field, option) => {
this.options[field] = option;
return (InputCmp) =>
React.cloneElement(InputCmp, {
name: field,
value: this.state[field] || "",
onChange: this.handleChange, //控件change
});
};
getFieldsValue = () => {
return { ...this.state };
};
getFieldValue = (field) => {
return this.state[field];
};
validateFields = (callback) => {
let errors = {};
const state = { ...this.state };
for (let field in this.options) {
if (state[field] === undefined) {
errors[field] = "error";
}
console.log("item", field); //sy-log
}
if (JSON.stringify(errors) === "{}") {
// 没有错误信息
callback(undefined, state);
} else {
// 有错误信息,返回
callback(errors, state);
}
};
render() {
return (
<div className="border">
<Cmp
{...this.props}
getFieldDecorator={this.getFieldDecorator}
getFieldsValue={this.getFieldsValue}
getFieldValue={this.getFieldValue}
validateFields={this.validateFields}
/>
</div>
);
}
};
}
总结
⾼阶组件(HOC)是 React 中⽤于复⽤组件逻辑的⼀种⾼级技巧。 HOC ⾃身不是 React API 的⼀部分,它是⼀种基于 React 的组合特性⽽形成的设计模式。注意 不要再render方法中使用HOC,因为每次在render中调用HOC那么每次得到组件都是新组件,这样就会触发React的Diff算法,执行挂载与卸载的操作,影响不必要的性能问题。