• antd-form 学习笔记


    AntD-Form 是基于 rc-form 来做了一层封装,我们看看它提供了哪些额外的功能

    先来看看 Form

    • 首先按照惯例获取SizeContext,ConfigContext,主要获取Size,getPrefixCls,direction,form.requiredMark.
    • 然后依次来获取 className,mergedRequiredMark.
    • 创建formInstance,这个是在rc.useForm封装了一层,添加了scrollToField(),getFieldInstance(),getFieldInstance(),这个是获取 Field 的 ReactElement.
    • FormContext 这个跟 rc 的FormContext 不一样,虽然名字一样(很容易让人误导),这个主要是布局相关的一些信息,还有 Field 对于的 ReactElement.
    • 封装了onFinishFailed 方法,根据配置scrollToFirstError 会让第一个错误进入 viewport.
    • 最后套上SizeContextProvider,FormContext.Provider 里面放上rc-Form.

    看看 FieldItem

    FieldItem 是在rc-Field 基础上添加了一些额外的功能。它主要添加了label,require 标记,tooltip,对于 input,它还添加了errorlist,gethelp 等,还有就是label 与 input的布局,通过colspan,offset来控制一共 24 个格子。这个里面有两个大的分支,布局以及rc-field的功能。布局要不要由noStyle控制,rc-field的功能阉割由!hasName && !isRenderProps && !dependencies控制

    if (!hasName && !isRenderProps && !dependencies) {
      return renderLayout(children) as JSX.Element;
    }
    
    • 首先获取从ConfigContext中获取getPrefixCls,从antd.FormContext中获取formName,requireMark,创建FormItemContext这里面就一个方法updateItemErrors: (name: string, errors: string[], originName?: string) => void
    • 最终每个FieldItemField被封装成,如下的结构。FormItemLabellabel,requiredrequiredMark决定,colon也由它接管,由colon控制。同时还可以支持tooltip。这里面有两个分支,一个是Field,另一个是普通的控件,跟 form 无关,另一个是Field。判断条件是
    • FieldItem里面还有一个noStyle, 这个值是控制是否要显示label,error,设置这个值表示,这些东西由父级接管了。
    if (!hasName && !isRenderProps && !dependencies) {
      return renderLayout(children) as JSX.Element;
    }
    
    <Row>
      <FormItemLabel />
      <FormItemInput>{children}</FormItemInput>
    </Row>
    
    • FieldItemInput 它其实包含inputDom, errorListDom, extraDom三部分,inputDom 如下,errorList 也如下。 ErrorList有点怪,功能很简单,就是把 error 挨个显示出来,但是用了一个 useCacheErrors,这个方法很简单,但是触发的过程确实好复杂。有好几层异步,还不明白为什么搞这么复杂。这段代码应该是打补丁打出来的。
    const inputDom = (
      <div className={`${baseClassName}-control-input`}>
        <div className={`${baseClassName}-control-input-content`}>{children}</div>
        {icon}
      </div>
    );
    
    const errorListDom = (
      <FormItemPrefixContext.Provider value={{ prefixCls, status }}>
        <ErrorList
          errors={errors}
          help={help}
          onDomErrorVisibleChange={onDomErrorVisibleChange}
        />
      </FormItemPrefixContext.Provider>
    );
    

    再聊聊几个参数组合使用的禁忌

    • shouldUpdatedependencies不可以同时使用。
    • 如果Item里面的 children 是数组,则不能使用 name。
    • 如果 children 是 renderProps,则必须跟 shouldUpdate 或者 dependencies 组合使用。同时 Field 不能使用 name,因为 renderProps 其实是一个可变的逻辑,它里面的内容才是 Field。
    • 如果设置了 dependencies, 要么指定名字,要么使用 renderProps。

    聊聊 dependencies vs shouldUpdate,

    • 共同点,这两个都是依据一定的条件决定当前的 Field 要不要刷新。
    • 不同点,dependencies,一般用于 validation, 也就是 upstream 的 Field 更新了,当前的 Field 要不要刷新,这个主要是用来激发验证的逻辑。如果当前的 Field 里面需要根据 upstream 里面的值来决定显示哪些 Field,那么这种情况下推荐用 shouldUpdate。因为,如果我们调用FormInstance.setFieldsValue() 时,这些隐藏的 Field 不会被刷新。只要用 shouldUpdate 才会。参考下面的例子。
      BugHere
    <Item name='gender'
                        label='Gender'
                        rules={[{required:true}]}
                    >
                        <Select
                            placeholder="Select a option and change input text above"
                            onChange={onGenderChange}
                            allowClear
                        >
                            <Option value='male'>Male</Option>
                            <Option value='female'>Female</Option>
                            <Option value='other'>Other</Option>
                        </Select>
                    </Item>
                    <Item dependencies={['gender']}
                        //shouldUpdate={(prev,cur)=>prev.gender!=cur.gender}
                        noStyle
                    >
                        {({getFieldValue})=>{
                            const gender = getFieldValue(['gender']);
                            return gender === 'other'?(
                                <Item name="customizeGender"
                                    label="Customize Gender"
                                    rules={[{required:true}]}
                                    >
                                        <Input/>
                                </Item>
                            ):null;
                        }}
                    </Item>
    
  • 相关阅读:
    HTML5基础
    错题本
    字符串
    带参的方法
    人际猜拳参考答案:
    用户登录页面——jdbc
    多媒体播放系统案例
    七言
    七言
    表格设计案例
  • 原文地址:https://www.cnblogs.com/kongshu-612/p/15039510.html
Copyright © 2020-2023  润新知