connect
描述
主要用于对第三方组件库的无侵入接入 Formily
签名
ts
import type { ConnectedComponent, JSXComponent } from '@silver-formily/react'
interface IComponentMapper<T extends JSXComponent> {
(target: T): JSXComponent
}
declare function connect<T extends JSXComponent>(
target: T,
...args: IComponentMapper<T>[]
): ConnectedComponent<T>入参传入第一个参数是要接入的组件,后面的参数都是组件映射器,每个映射器都是一个函数,通常我们会使用内置的mapProps和mapReadPretty映射器
connect 内部会用 forwardRef 包裹目标组件并透传 ref,同时通过 hoist-non-react-statics 提升目标组件的静态属性。
用例
tsx
import { createForm, isVoidField, setValidateLanguage } from '@silver-formily/core'
import { connect, Field, FormConsumer, FormProvider, mapProps } from '@silver-formily/react'
import { Button, Form, Input } from 'antd'
setValidateLanguage('en')
// Form.Item 的错误文案/help 不叫 selfErrors,用 connect + mapProps 把字段状态映射过去
const FormItem = connect(
Form.Item,
mapProps(
{
title: 'label',
description: 'extra',
required: true,
validateStatus: true,
},
(props, field) => ({
...props,
help: !isVoidField(field) && field.selfErrors.length
? field.selfErrors.join(', ')
: undefined,
}),
),
)
const form = createForm({ validateFirst: true })
function log(...args: unknown[]) {
console.log(...args)
}
function handleSubmit() {
form.submit(log)
}
export default function Demo() {
return (
<FormProvider form={form}>
<Form layout="vertical">
<Field
name="name"
title="Name"
required
decorator={[FormItem]}
component={[Input, { placeholder: 'Please Input' }]}
/>
<FormConsumer>
{_form => (
<>
<div style={{ whiteSpace: 'pre', marginBottom: 16 }}>
{JSON.stringify(_form.values, null, 2)}
</div>
<Button type="primary" onClick={handleSubmit}>
Submit
</Button>
</>
)}
</FormConsumer>
</Form>
</FormProvider>
)
}tsx
import { createForm, isVoidField, setValidateLanguage } from '@silver-formily/core'
import { connect, Field, FormConsumer, FormProvider, mapProps } from '@silver-formily/react'
import { Button, Form, Input } from 'antd'
setValidateLanguage('en')
// Form.Item 的错误文案/help 不叫 selfErrors,用 connect + mapProps 把字段状态映射过去
const FormItem = connect(
Form.Item,
mapProps(
{
title: 'label',
description: 'extra',
required: true,
validateStatus: true,
},
(props, field) => ({
...props,
help: !isVoidField(field) && field.selfErrors.length
? field.selfErrors.join(', ')
: undefined,
}),
),
)
const form = createForm({ validateFirst: true })
function log(...args: unknown[]) {
console.log(...args)
}
function handleSubmit() {
form.submit(log)
}
export default function Demo() {
return (
<FormProvider form={form}>
<Form layout="vertical">
<Field
name="name"
title="Name"
required
decorator={[FormItem]}
component={[Input, { placeholder: 'Please Input' }]}
/>
<FormConsumer>
{_form => (
<>
<div style={{ whiteSpace: 'pre', marginBottom: 16 }}>
{JSON.stringify(_form.values, null, 2)}
</div>
<Button type="primary" onClick={handleSubmit}>
Submit
</Button>
</>
)}
</FormConsumer>
</Form>
</FormProvider>
)
}
查看源码
ConnectedComponent<T> 将原组件 props 变为可选,保留 ref 目标类型和提升后的自定义静态成员,排除 React 元信息。映射器按参数顺序应用。mapProps / mapReadPretty 本身返回 ComponentType<any>,连接后公开 props 的精度来自原始目标组件。