@rc-component/form
v1.8.6
Published
React Form Component
Readme
特性
| 范围 | 支持 |
| ------ | ---------------------------------------------------------------- |
| 状态 | 字段级订阅、受控字段和初始值 |
| 验证 | 由 @rc-component/async-validator 支持的基于规则的验证 |
| 结构 | 嵌套名称、列表、依赖和保留控制 |
| 接口 | Form、Field、List、FormProvider、useForm 和 useWatch |
| 运行时 | 兼容 React DOM 和 React Native 的表单状态模型 |
安装
npm install @rc-component/form该包过去以 rc-field-form 名称记录;新安装请使用 @rc-component/form。
使用
import Form, { Field } from '@rc-component/form';
const Input = ({ value = '', ...props }) => <input value={value} {...props} />;
const Demo = () => {
return (
<Form
onFinish={values => {
console.log('Finish:', values);
}}
>
<Field name="username">
<Input placeholder="Username" />
</Field>
<Field name="password">
<Input placeholder="Password" />
</Field>
<button>Submit</button>
</Form>
);
};
export default Demo;示例
运行本地 dumi 站点:
npm install
npm start然后打开 http://localhost:8000。
API
我们使用 TypeScript 生成类型定义,可直接在 IDE 中查看,也可以查看这里的类型定义。
Form
| 属性 | 说明 | 类型 | 默认值 |
| ---------------- | ------------------------------------------------- | -------------------------------------------- | ---------------- |
| component | 自定义表单渲染组件 | string | Component | false | form |
| fields | 控制 Form 字段状态,仅在 Redux 等外部状态场景使用 | FieldData[] | - |
| form | 设置由 useForm 创建的表单实例 | FormInstance | Form.useForm() |
| initialValues | 表单初始值 | Object | - |
| name | 配合 FormProvider 使用的表单名称 | string | - |
| preserve | 删除字段后保留值 | boolean | false |
| validateMessages | 设置验证消息模板 | ValidateMessages | - |
| onFieldsChange | 任意字段状态变化时触发 | (changedFields, allFields) => void | - |
| onFinish | 表单提交成功时触发 | (values) => void | - |
| onFinishFailed | 表单提交失败时触发 | ({ values, errorFields, outOfDate }) => void | - |
| onValuesChange | 任意字段值变化时触发 | (changedValues, values) => void | - |
Field
| 属性 | 说明 | 类型 | 默认值 |
| ----------------- | ---------------------------------------------------- | ---------------------------------------------- | -------- |
| dependencies | 如果依赖项发生变化,将重新渲染 | NamePath[] | - |
| getValueFromEvent | 指定如何从事件中获取值 | (..args: any[]) => any | - |
| getValueProps | 基于值自定义额外 props。该属性会禁用 valuePropName | (value) => any | - |
| initialValue | 字段初始值 | any | - |
| name | 字段名称路径 | NamePath | - |
| normalize | 更新前标准化值 | (value, prevValue, prevValues) => any | - |
| preserve | 删除字段后保留值 | boolean | false |
| rules | 验证规则 | Rule[] | - |
| shouldUpdate | 检查字段是否应该更新 | boolean | (prevValues, nextValues) => boolean | - |
| trigger | 通过事件触发收集值更新 | string | onChange |
| validateTrigger | 使用规则验证配置触发点 | string | string[] | onChange |
| valuePropName | 配置元素中映射值的 prop | string | value |
List
| 属性 | 说明 | 类型 | 默认值 | | -------- | ------------------ | ------------------------------------------------------------------------------------------------------- | ------ | | name | 列表字段名称路径 | NamePath[] | - | | children | 列表字段的渲染函数 | (fields: { name: NamePath }[], operations: ListOperations) => ReactNode | - |
useForm
Form 组件默认通过 Form.useForm 创建表单实例。你也可以手动创建实例并传给 Form,从而直接调用表单实例上的方法。
const Demo = () => {
const [form] = Form.useForm();
return <Form form={form} />;
};对于类组件用户,可以使用 ref 来获取表单实例:
class Demo extends React.Component {
setRef = form => {
// 在这里访问 Form 实例
};
render() {
return <Form ref={this.setRef} />;
}
}| 属性 | 说明 | 类型 | | ----------------- | ------------------------------ | -------------------------------------------------------------------------- | | getFieldValue | 通过名称路径获取字段值 | (name: NamePath) => any | | getFieldsValue | 按名称路径列表获取字段值列表 | (nameList?: (NamePath[]) => any) | true | | getFieldError | 按名称路径获取字段错误 | (name: NamePath) => string[] | | getFieldsError | 按名称路径列表获取字段错误列表 | (nameList?: NamePath[]) => FieldError[] | | isFieldsTouched | 检查字段列表是否被触及 | (nameList?: NamePath[], allTouched?: boolean) => boolean | | isFieldTouched | 检查某个字段是否被触摸 | (name: NamePath) => boolean | | isFieldValidating | 检查字段是否正在校验 | (name: NamePath) => boolean | | resetFields | 重置字段状态 | (fields?: NamePath[]) => void | | setFields | 设置字段状态 | (fields: FieldData[]) => void | | setFieldsValue | 设置字段值 | (values) => void | | submit | 触发表单提交 | () => void | | validateFields | 触发字段进行验证 | (nameList?: NamePath[], options?: ValidateOptions) => Promise |
FormProvider
| 属性 | 说明 | 类型 | 默认值 |
| ---------------- | -------------------------------- | ---------------------------------------- | ------ |
| validateMessages | 配置全局 validateMessages 模板 | ValidateMessages | - |
| onFormChange | 命名表单字段变化时触发 | (name, { changedFields, forms }) => void | - |
| onFormFinish | 命名表单提交完成时触发 | (name, { values, forms }) => void | - |
接口
NamePath
| 类型 | | ---------------------------------------- | | string | number | (string | number)[] |
FieldData
| 属性 | 类型 | | ---------- | ---------------------------------------- | | touched | boolean | | validating | boolean | | errors | string[] | | name | string | number | (string | number)[] | | value | any |
Rule
| 属性 | 类型 | | --------------- | ----------------------------------------------------------------------------------------------- | | enum | any[] | | len | number | | max | number | | message | string | | min | number | | pattern | RegExp | | required | boolean | | transform | (value) => any | | type | string | | validator | (rule, value, callback: (error?: string) => void, form) => Promise | void | | whitespace | boolean | | validateTrigger | string | string[] |
validator
为了与 validator 的 rc-form 旧用法保持同步,我们仍然提供 callback 来触发验证完成。但在 rc-field-form 中,我们强烈建议返回 Promise。
ListOperations
| 属性 | 类型 | | ------ | ------------------------ | | add | (initValue: any) => void | | remove | (index: number) => void |
ValidateMessages
验证消息提供错误模板列表。您可以参考此处以获得完全默认的模板。
| 属性 | 说明 |
| ------- | ---------------------- |
| enum | Rule 的 enum 属性 |
| len | Rule 的 len 属性 |
| max | Rule 的 max 属性 |
| min | Rule 的 min 属性 |
| name | 字段名称 |
| pattern | Rule 的 pattern 属性 |
| type | Rule 的 type 属性 |
与 rc-form 的差异
rc-field-form 尝试在 api 级别与 rc-form 保持同步,但仍有一些需要更改的地方:
1. 未操作过的 Field 不会再与 initialValues 保持同步
在 rc-form 中,如果用户不对其进行操作,字段值将从 initialValues 获取。
这是一个错误,但用户将其用作一项功能,这使得修复将是一个重大更改,我们必须保留它。
在 Field Form 中,这个问题不再存在。如果要更改字段值,请改用 setFieldsValue。
2. 移除 Field 不会清理对应值
过去我们在 Field 删除时清理对应值。但根据用户反馈,清理已有值会给条件字段保留值的场景增加额外成本。
3. 嵌套 name 使用数组而不是字符串
在 rc-form 中,我们支持像 user.name 这样的名称并将值转换为 { user: { name: 'Bamboo' } }。这使得“.”始终是变量的路径,这使得开发人员必须做额外的工作,如果名称是真实的,其中包含像 app.config.start 这样的点,则必须在提交时解析回该点。
Field Form 只会将 ['user', 'name'] 转换为 { user: { name: 'Bamboo' } },而 user.name 会转换为 { ['user.name']: 'Bamboo' }。
4. 移除 validateFieldsAndScroll
由于 findDomNode 在 StrictMode 中被标记为警告。这已经超出了 Form 组件本身的控制范围。
我们决定删除 validateFieldsAndScroll 方法,您应该用自己的逻辑处理它:
<Form>
<Field name="username">
<input ref={this.inputRef} />
</Field>
</Form>5. getFieldsError 始终返回数组
当没有错误发生时,rc-form 返回null。这使得用户必须执行一些额外的代码,例如:
(form.getFieldsError('fieldName') || []).forEach(() => {
// Do something...
});现在如果没有错误,getFieldsError 将返回 []。
6. 移除 validateFields 的 callback
由于 ES8 支持 async/await,所以没有理由不使用它。现在您可以轻松处理您的验证逻辑:
async function() {
try {
const values = await form.validateFields();
console.log(values);
} catch (errorList) {
errorList.forEach(({ name, errors }) => {
// Do something...
});
}
}注意:现在,如果您的验证器返回 Error(message),则不需要通过 e => e.message 获得错误。 FieldForm 将处理这个问题。
7. preserve 默认值为 false
在 rc-form 中,您应该使用 preserve 来保留值,因为表单会自动从删除的字段中删除值。无论字段被删除,字段表单将始终将值保留在表单中。但您仍然可以使用 preserve=false 来禁用自 1.5.0 以来的值保留。
8. setFields 不触发 onFieldsChange,setFieldsValue 不触发 onValuesChange
在 rc-form 中,我们希望通过设置使 redux 调度更容易来帮助用户自动触发更改事件,但这不是一个好的设计,因为它使代码逻辑耦合。
此外,用户控制更新触发onFieldsChange和onValuesChange事件具有潜在的死循环风险。
本地开发
npm install
npm start
npm test
npm run lint
npm run tsc
npm run compile
npm run builddumi 站点默认运行在 http://localhost:8000。
发布
npm run prepublishOnly包构建完成后,发布流程由 @rc-component/np 通过 rc-np 命令处理。
许可证
@rc-component/form 基于 MIT 许可证发布。
