Skip to content

Commit b3da54b

Browse files
committed
fix(Form): 兼容自定义组件
1 parent f67c8ba commit b3da54b

File tree

4 files changed

+47
-18
lines changed

4 files changed

+47
-18
lines changed

example/examples/src/routes/Form/index.tsx

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
11
import React from 'react';
2-
import {Form, Button, Toast} from '@uiw/react-native';
2+
import {Form, Button, Toast, Slider, SearchBar} from '@uiw/react-native';
33
import Layout, {Container} from '../../Layout';
44
const {Body, Footer} = Layout;
55

66
const FormDemo = () => {
77
const form = Form.useForm({
88
changeValidate: true,
9+
watch: {
10+
name: (value: unknown) => {
11+
console.log('value', value);
12+
},
13+
},
14+
customComponentList: {
15+
render: <Slider />,
16+
},
917
});
1018
const items = [
1119
{
@@ -92,6 +100,11 @@ const FormDemo = () => {
92100
step: 0.2,
93101
},
94102
},
103+
{
104+
type: 'render',
105+
field: 'render',
106+
name: '自定义',
107+
},
95108
];
96109
const initialValues = {name: '王滴滴'};
97110

packages/core/src/Form/formItems.tsx

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React, { FC, useContext } from 'react';
22
import { KeyType, FormItemsProps } from './types';
3+
import { isObjectEmpty } from './utils/is';
34
import { Context } from './hooks/context';
45
import Radio from '../Radio';
56
import CheckBox from '../CheckBox';
@@ -15,23 +16,22 @@ import { View, Text, SafeAreaView, StyleSheet, TextInput } from 'react-native';
1516

1617
const FormItems: FC<any> = ({ formDatas = [] }) => {
1718
const {
18-
innerMethods: { store = {}, updateStore, validator, innerValidate },
19+
innerMethods: { store = {}, updateStore, validator, innerValidate, watch, customComponentList },
1920
} = useContext(Context);
2021

21-
const change = (field: KeyType, value: any) => updateStore?.({ store: { ...store, [field]: value } });
22+
const change = (field: KeyType, value: unknown) => {
23+
updateStore?.({ store: { ...store, [field]: value } });
24+
watch[field]?.(value);
25+
};
2226

2327
const _renderComponent = (v: FormItemsProps) => {
2428
const options = v.options || [];
25-
if (v.type === 'render') {
26-
return v.render;
27-
}
2829
if (v.type === 'input') {
2930
return (
3031
<TextInput
3132
value={store[v.field]}
3233
onChangeText={(value) => {
3334
change(v.field, value);
34-
v?.attr?.onChangeText?.(value);
3535
innerValidate();
3636
}}
3737
{...v.attr}
@@ -43,7 +43,6 @@ const FormItems: FC<any> = ({ formDatas = [] }) => {
4343
<TextArea
4444
onChange={(value: string) => {
4545
change(v.field, value);
46-
v?.attr?.onChange?.(value);
4746
innerValidate();
4847
}}
4948
value={store[v.field]}
@@ -58,7 +57,6 @@ const FormItems: FC<any> = ({ formDatas = [] }) => {
5857
checked={item.value === store[v.field]}
5958
onPress={() => {
6059
change(v.field, item.value);
61-
v?.attr?.onPress?.(item.value);
6260
innerValidate();
6361
}}
6462
{...v.attr}
@@ -83,7 +81,6 @@ const FormItems: FC<any> = ({ formDatas = [] }) => {
8381
data.splice(idx, 1);
8482
}
8583
change(v.field, data);
86-
v?.attr?.onChange?.(data);
8784
innerValidate();
8885
}}
8986
{...v.attr}
@@ -98,7 +95,6 @@ const FormItems: FC<any> = ({ formDatas = [] }) => {
9895
<Rating
9996
onPress={(number) => {
10097
change(v.field, number);
101-
v?.attr?.onPress?.(number);
10298
innerValidate();
10399
}}
104100
{...v.attr}
@@ -111,7 +107,6 @@ const FormItems: FC<any> = ({ formDatas = [] }) => {
111107
checked={store[v.field]}
112108
onValueChange={(value) => {
113109
change(v.field, !store[v.field]);
114-
v?.attr?.onValueChange?.(value);
115110
innerValidate();
116111
}}
117112
{...v.attr}
@@ -124,7 +119,6 @@ const FormItems: FC<any> = ({ formDatas = [] }) => {
124119
options={options}
125120
onChange={(value) => {
126121
change(v.field, value);
127-
v?.attr?.onChange?.(value);
128122
innerValidate();
129123
}}
130124
contentStyle={{ paddingHorizontal: 0 }}
@@ -141,7 +135,6 @@ const FormItems: FC<any> = ({ formDatas = [] }) => {
141135
value={store[v.field]}
142136
onChange={(value) => {
143137
change(v.field, value);
144-
v?.attr?.onChange?.(value);
145138
innerValidate();
146139
}}
147140
{...v.attr}
@@ -154,13 +147,24 @@ const FormItems: FC<any> = ({ formDatas = [] }) => {
154147
value={store[v.field]}
155148
onChange={(value) => {
156149
change(v.field, value);
157-
v?.attr?.onChange?.(value);
158150
innerValidate();
159151
}}
160152
{...v.attr}
161153
/>
162154
);
163155
}
156+
// 自定义组件
157+
if (!isObjectEmpty(customComponentList) && Object.keys(customComponentList).includes(v.type)) {
158+
return React.isValidElement(customComponentList[v.type])
159+
? React.cloneElement(customComponentList[v.type], {
160+
...v.attr,
161+
onChange: (value: unknown) => {
162+
change(v.field, value);
163+
innerValidate();
164+
},
165+
})
166+
: null;
167+
}
164168
return null;
165169
};
166170

packages/core/src/Form/hooks/useForm.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import React from 'react';
12
import { KeyType, InnerMethodsReturnType, FormInstance } from '../types';
23
import { useState } from 'react';
34
import { useValidator } from '@validator.tool/hook';
@@ -13,7 +14,15 @@ export default function useForm<
1314
FormData = any,
1415
FieldValue = FormData[keyof FormData],
1516
FieldKey extends KeyType = keyof FormData,
16-
>({ changeValidate = false }: { changeValidate?: boolean }): FormInstance<FormData, FieldValue, FieldKey> {
17+
>({
18+
changeValidate = false,
19+
watch = {},
20+
customComponentList,
21+
}: {
22+
changeValidate?: boolean;
23+
watch?: Partial<Record<string, (value: unknown) => void>>;
24+
customComponentList?: Partial<Record<string, unknown>>;
25+
}): FormInstance<FormData, FieldValue, FieldKey> {
1726
const [state, setState] = useState<State>({
1827
initialValues: {},
1928
store: {},
@@ -102,6 +111,8 @@ export default function useForm<
102111
validator,
103112
forceUpdate,
104113
innerValidate,
114+
watch,
115+
customComponentList,
105116
};
106117
}
107118
return methods;

packages/core/src/Form/types/index.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { RulesOption } from '@validator.tool/hook';
2-
import React from 'react';
32
import Validator from 'validator.tool';
43

54
type KeyType = string | number | symbol;
@@ -11,6 +10,8 @@ export type InnerMethodsReturnType<FormData = any> = {
1110
validator: Validator;
1211
forceUpdate: () => void;
1312
innerValidate: () => void;
13+
watch: Partial<Record<string, (value: unknown) => void>>;
14+
customComponentList: Partial<Record<string, JSX.Element>>;
1415
};
1516

1617
type FormInstance<FormData = any, FieldValue = FormData[keyof FormData], FieldKey extends KeyType = keyof FormData> = {
@@ -36,7 +37,7 @@ interface FormItemsProps {
3637
options?: Array<{ label: string; value: KeyType | any }>;
3738
attr?: any;
3839
required?: boolean;
39-
render?: React.ReactNode;
40+
render?: JSX.Element;
4041
}
4142

4243
export type { FormProps, FormItemsProps, KeyType, FormInstance };

0 commit comments

Comments
 (0)