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,如果表单非常大的时候。。。

相关推荐
支付宝体验科技2 小时前
支付宝 KJS Compose 动态化方案与架构设计
前端·客户端
AllinLin2 小时前
JS中的call apply bind全面解析
前端·javascript·vue.js
阿乐去买菜2 小时前
2025 年末 TypeScript 趋势洞察:AI Agent 与 TS 7.0 的原生化革命
前端
POLITE32 小时前
Leetcode 438. 找到字符串中所有字母异位词 JavaScript (Day 4)
javascript·算法·leetcode
创思通信2 小时前
STM32F103C8T6采 DS18B20,通过A7680C 4G模块不断发送短信到手机
javascript·stm32·智能手机
海绵宝龙2 小时前
Vue 中的 Diff 算法
前端·vue.js·算法
zhougl9962 小时前
vue中App.vue和index.html冲突问题
javascript·vue.js·html
止观止2 小时前
告别全局污染:深入理解 ES Modules 模块化与构建工具
javascript·webpack·vite·前端工程化·es modules
浩泽学编程2 小时前
内网开发?系统环境变量无权限配置?快速解决使用其他版本node.js
前端·vue.js·vscode·node.js·js