sedationh / blog

Blog space for a user who doesn't want to mess with blogs anymore:)
0 stars 0 forks source link

Antd Form 3 和 HOC #96

Open sedationh opened 1 month ago

sedationh commented 1 month ago

资料

文档看这里 https://3x.ant.design/components/form-cn/

代码看这里 https://github.com/react-component/form

做了什么?

封装了通用的表单能力,如取值,校验,报错等

import { createForm, formShape } from 'rc-form';

class A extends React.Component {
  static propTypes = {
    form: formShape,
  };

  submit = () => {
    this.props.form.validateFields((error, value) => {
      console.log(error, value);
    });
  }

  render() {
    let errors;
    const { getFieldProps, getFieldError } = this.props.form;
    return (
      <div>
        <input {...getFieldProps('normal')}/>
        <input {...getFieldProps('required', {
          onChange(){}, // have to write original onChange here if you need
          rules: [{required: true}],
        })}/>
        {(errors = getFieldError('required')) ? errors.join(',') : null}
        <button onClick={this.submit}>submit</button>
      </div>
    );
  }
}

export createForm()(A);

通过 HOC 的模式来实现

一些概念

HOC Higher-Order Components A higher-order component (HOC) is an advanced technique in React for reusing component logic. HOCs are not part of the React API, per se. They are a pattern that emerges from React’s compositional nature. Concretely, a higher-order component is a function that takes a component and returns a new component.

Wiki 中有说什么是高阶函数 在数学和计算机科学中,高阶函数是至少满足下列一个条件的函数:

具体咋做的

写 Form 的组件 A 需要被 createForm()(A) 包一下

A 中可以从 props 中拿到 form this.props.form

搞 HOC 就是为了让内部表单可以共用状态和逻辑,但是共用状态会导致改变任意表单项目会触发整个表单的 rerender,这个性能问题在复杂表单场景有较大性能问题

实现一遍

https://github.com/sedationh/react-ui/blob/main/src/components/FormV3/index.tsx

效果见 https://react-ui-three.vercel.app/?path=/story/components-formv3--default

其他

之前工作里搞UI 和 逻辑分离的时候,同样用了这个模式 https://github.com/sedationh/react-ui-logic-separation/blob/19d405e3a3d1e462c0f9999688a032e87072beb7/src/App.tsx#L66-L79