被设置了 name 属性的 Form.Item 包装的控件,表单控件会自动添加 value(或 valuePropName 指定的其他属性) onChange(或 trigger 指定的其他属性),数据同步将被 Form 接管,这会导致以下结果:
你不再需要也不应该用 onChange 来做数据收集同步(你可以使用 Form 的 onValuesChange),但还是可以继续监听 onChange 事件。
你不能用控件的 value 或 defaultValue 等属性来设置表单域的值,默认值可以用 Form 里的 initialValues 来设置。注意 initialValues 不能被 setState 动态更新,你需要用 setFieldsValue 来更新。
你不应该用 setState,可以使用 form.setFieldsValue 来动态改变表单值。
以上为官方文档描述,简单的 name、valuePropName 绑定子控件进行 form value设置。
有时候我们可能想要自定义进行值的转换。
需要用到
shouldUpdate
Form 通过增量更新方式,只更新被修改的字段相关组件以达到性能优化目的。大部分场景下,你只需要编写代码或者与 dependencies
属性配合校验即可。而在某些特定场景,例如修改某个字段值后出现新的字段选项、或者纯粹希望表单任意变化都对某一个区域进行渲染。你可以通过 shouldUpdate
修改 Form.Item 的更新逻辑。
当 shouldUpdate
为 true
时,Form 的任意变化都会使该 Form.Item 重新渲染。这对于自定义渲染一些区域十分有帮助:
<Form.Item shouldUpdate>
{() => {
return <pre>{JSON.stringify(form.getFieldsValue(), null, 2)}</pre>;
}}
</Form.Item>
你可以参考示例查看具体使用场景。
当 shouldUpdate
为方法时,表单的每次数值更新都会调用该方法,提供原先的值与当前的值以供你比较是否需要更新。这对于是否根据值来渲染额外字段十分有帮助:
<Form.Item shouldUpdate={(prevValues, curValues) => prevValues.additional !== curValues.additional}>
{() => {
return (
<Form.Item name="other">
<Input />
</Form.Item>
);
}}
</Form.Item>
你可以参考示例查看具体使用场景。
form 是哪里来的
通过fc渲染来获取进行shouldUpdate刷新渲染实现外部隔离
import { ProFormItem } from '@ant-design/pro-components';
import { Switch } from 'antd';
export type ProFormSwitchWzcPropType<T, F> = {
valueEnum: {
true: {
label: string;
value: T;
};
false: {
label: string;
value: T;
};
};
/**
* form item name
*/
name: string;
label: string;
};
const ProFormSwitchWzc = <T, F>(prop: ProFormSwitchWzcPropType<T, F>) => {
return (
<ProFormItem label={prop.label} shouldUpdate>
{(form) => {
return (
<Switch
checkedChildren={prop.valueEnum.true.label}
unCheckedChildren={prop.valueEnum.false.label}
checked={
form.getFieldValue(prop.name) === prop.valueEnum.true.value
}
onChange={(ck) =>
form?.setFieldValue(
prop.name,
prop.valueEnum[ck ? 'true' : 'false'].value,
)
}
></Switch>
);
}}
</ProFormItem>
);
};
export default ProFormSwitchWzc;
使用
<ProForm<AccountEditReq>
onFinish={handleFinish}
formRef={formRef}
params={routerParams}
formKey="accountItem"
dateFormatter={(value, valueType) => {
console.log('---->', value, valueType);
return value.format('YYYY/MM/DD HH:mm');
}}
request={handlePageInit}
autoFocusFirstInput
>
<ProFormSwitch
name="adminFlag"
label="超級管理員"
checkedChildren="是"
unCheckedChildren="否"
/>
<ProFormSwitchWzcPropType<number, AccountEditReq>
valueEnum={{
true: {
label: '正常',
value: 0,
},
false: {
label: '锁定',
value: 1,
},
}}
name="lockFlag"
label="锁定账户"
></ProFormSwitchWzcPropType>
</ProForm>