antd3的表单实现(HOC解决方案)

使用的是装饰器 @createForm

js 复制代码
// MyRCFormPage.js
import React, { Component } from "react";
import createForm from "../components/my-rc-form/index";
import Input from "../components/input";

const nameRules = { required: true, message: "请输入姓名!" };
const passwordRules = { required: true, message: "请输入密码!" };

@createForm
class MyRCFormPage extends Component {
  componentDidMount() {
    this.props.form.setFieldsValue({ username: "default" });
  }
  submit = () => {
    this.props.form.validateFields((err, values) => {
      if (err) {
        console.log(err);
      } else {
        console.log(values);
      }
    });
  };
  render() {
    const { getFieldDecorator } = this.props.form;
	console.log('render');
		
    return (
      <div>
        <h3>MyRCFormPage</h3>
        {getFieldDecorator("username", { rules: [nameRules] })(
          <Input placeholder="Username" />
        )}
        {getFieldDecorator("password", { rules: [passwordRules] })(
          <Input placeholder="Password" />
        )}
        <button onClick={this.submit}>submit</button>
      </div>
    );
  }
}

export default MyRCFormPage;
js 复制代码
// input.js
import { Component } from "react";

const Input = (props) => {
  return <input {...props} />;
};

class CustomizeInput extends Component {
  render() {
    const { value = "", ...otherProps } = this.props;
    return (
      <div style={{ padding: 10 }}>
        <Input style={{ outline: "none" }} value={value} {...otherProps} />
      </div>
    );
  }
}

export default CustomizeInput;
js 复制代码
// my-rc-form/index.js
import React, { Component } from "react";

export default function createForm(Cmp) {
  return class extends Component {
    constructor(props) {
      super(props);
      this.state = {};
      this.options = {}; // 保存表单项的配置
    }
    handleChange = (e) => {
      const { name, value } = e.target;
      this.setState({
        [name]: value,
      });
    };
    getFieldDecorator = (field, option) => (InputCmp) => {
      this.options[field] = option;
      return React.cloneElement(InputCmp, {
        name: field,
        value: this.state[field],
        onChange: this.handleChange,
      });
    };
    setFieldsValue = (newStore) => {
      this.setState(newStore);
    };
    getFieldsValue = () => {
      return {
        ...this.state,
      };
    };
    validateFields = (callback) => {
      let err = [];
      // 校验
      for (let field in this.options) {
        if (this.state[field] === undefined) {
          err.push({ [field]: "error" });
        }
      }
      callback(err.length ? err : null, this.state);
    };
    getForm = () => {
      return {
        form: {
          getFieldDecorator: this.getFieldDecorator,
          setFieldsValue: this.setFieldsValue,
          getFieldsValue: this.getFieldsValue,
          validateFields: this.validateFields,
        },
      };
    };
    render() {
      return <Cmp {...this.props} {...this.getForm()} />;
    }
  };
}

现在的问题是当一个表单item发生改变时,整个表单都要重新执行render,如果表单非常大的时候。。。

相关推荐
子兮曰4 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰4 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万4 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝4 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋4 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁4 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
李少兄4 天前
JavaScript 隐式全局变量解析
javascript
汉堡大王95274 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大4 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端
计算机魔术师4 天前
Meta Muse agent 接入 Shopify 的 Shop Pay 实现代理式购物
前端