Skip to content

Commit 16a9436

Browse files
committed
fix(Form): 组件渲染遍历优化
1 parent a28c67a commit 16a9436

File tree

11 files changed

+163
-287
lines changed

11 files changed

+163
-287
lines changed

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

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -111,21 +111,16 @@ const FormDemo = () => {
111111
type: 'cardList',
112112
field: 'cardList',
113113
name: '动态list',
114-
validate: (val: any) => {
115-
console.log('val', val);
116-
return '';
117-
},
118114
items: [
119115
{
120116
type: 'input',
121117
field: 'cardListItem1',
122118
name: '动态表单项1',
123-
required: true,
124119
},
125120
],
126121
},
127122
];
128-
const initialValues = {name: '王滴滴'};
123+
const initialValues = {name: '王滴滴', rate: 4};
129124

130125
return (
131126
<Container>
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import React from 'react';
2+
import { KeyType } from '../types';
3+
import CheckBox, { CheckBoxProps } from '../../CheckBox';
4+
5+
interface FormCheckBoxProps extends CheckBoxProps {
6+
value?: KeyType[];
7+
onChange?: (value: KeyType[] | boolean) => void;
8+
options?: Array<{ label: string; value: KeyType }>;
9+
}
10+
11+
const FormCheckBox = ({ value = [], onChange, options = [], ...others }: FormCheckBoxProps) => {
12+
return (
13+
<React.Fragment>
14+
{options.map((item, idx) => {
15+
return (
16+
<CheckBox
17+
key={idx}
18+
checked={value.includes(item.value)}
19+
onChange={() => {
20+
let data = value || [];
21+
if (!data.includes(item.value)) {
22+
data.push(item.value);
23+
} else {
24+
const idx = data.findIndex((v: KeyType) => v === item.value);
25+
data.splice(idx, 1);
26+
}
27+
onChange?.(data);
28+
}}
29+
{...others}
30+
>
31+
{item.label}
32+
</CheckBox>
33+
);
34+
})}
35+
</React.Fragment>
36+
);
37+
};
38+
39+
export default FormCheckBox;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import React from 'react';
2+
import { TextInput, TextInputProps } from 'react-native';
3+
4+
const Input = ({ value, onChange, ...others }: TextInputProps & { onChange?: (value: string) => void }) => {
5+
return (
6+
<TextInput
7+
value={value}
8+
onChangeText={(value) => {
9+
onChange?.(value);
10+
}}
11+
{...others}
12+
/>
13+
);
14+
};
15+
16+
export default Input;
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import React from 'react';
2+
import { KeyType } from '../types';
3+
import Radio, { RadioProps } from '../../Radio';
4+
5+
interface FormRadioProps extends RadioProps {
6+
value?: KeyType;
7+
onChange?: (value: KeyType) => void;
8+
options?: Array<{ label: string; value: KeyType }>;
9+
}
10+
11+
const FormRadio = ({ value, onChange, options = [], ...others }: FormRadioProps) => {
12+
return (
13+
<React.Fragment>
14+
{options.map((item, idx) => (
15+
<Radio
16+
key={idx}
17+
checked={item.value === value}
18+
onPress={() => {
19+
onChange?.(item.value);
20+
}}
21+
{...others}
22+
>
23+
{item.label}
24+
</Radio>
25+
))}
26+
</React.Fragment>
27+
);
28+
};
29+
30+
export default FormRadio;
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import React from 'react';
2+
import Rating, { RatingProps } from '../../Rating';
3+
4+
const Rate = ({ onChange, ...others }: RatingProps & { onChange?: (value: number) => void }) => {
5+
return (
6+
<Rating
7+
onPress={(value) => {
8+
onChange?.(value);
9+
}}
10+
{...others}
11+
/>
12+
);
13+
};
14+
15+
export default Rate;
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import React from 'react';
2+
import Switch, { SwitchProps } from '../../Switch';
3+
4+
const FormSwitch = ({
5+
value,
6+
onChange,
7+
...others
8+
}: SwitchProps & { onChange?: (value: boolean) => void; value?: boolean }) => {
9+
return (
10+
<Switch
11+
checked={value}
12+
onValueChange={() => {
13+
onChange?.(!value);
14+
}}
15+
{...others}
16+
/>
17+
);
18+
};
19+
20+
export default FormSwitch;

packages/core/src/Form/form.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ const Form = <
3131

3232
return (
3333
<Provider contextProps={contextProps}>
34-
<FormItems formDatas={formDatas} initialValues={initialValues} />
34+
<FormItems formDatas={formDatas} />
3535
</Provider>
3636
);
3737
};

packages/core/src/Form/formItems.tsx

Lines changed: 3 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,16 @@ import React, { FC, useContext } from 'react';
22
import { KeyType, FormItemsProps } from './types';
33
import { isObjectEmpty } from './utils/is';
44
import { Context } from './hooks/context';
5-
import Radio from '../Radio';
6-
import CheckBox from '../CheckBox';
7-
import Rating from '../Rating';
8-
import Switch from '../Switch';
9-
import SearchBar from '../SearchBar';
10-
import FormDatePicker from './comps/datePicker';
115
import Stepper from '../Stepper';
12-
import TextArea from '../TextArea';
13-
import Slider from '../Slider';
146
import Label from './comps/label';
157
import Tip from './comps/tip';
168
import FormList from './formList';
17-
import { View, SafeAreaView, StyleSheet, TextInput } from 'react-native';
9+
import { View, SafeAreaView } from 'react-native';
1810
import styles from './styles';
1911

2012
const FormItems: FC<any> = ({ formDatas = [] }) => {
2113
const {
22-
innerMethods: { store = {}, updateStore, validator, innerValidate, watch, customComponentList },
14+
innerMethods: { store = {}, updateStore, innerValidate, watch, customComponentList, initialValues },
2315
} = useContext(Context);
2416

2517
const change = (field: KeyType, value: unknown) => {
@@ -28,141 +20,14 @@ const FormItems: FC<any> = ({ formDatas = [] }) => {
2820
};
2921

3022
const _renderComponent = (v: FormItemsProps) => {
31-
const options = v.options || [];
32-
if (v.type === 'input') {
33-
return (
34-
<TextInput
35-
value={store[v.field]}
36-
onChangeText={(value) => {
37-
change(v.field, value);
38-
innerValidate();
39-
}}
40-
{...v.attr}
41-
/>
42-
);
43-
}
44-
if (v.type === 'textArea') {
45-
return (
46-
<TextArea
47-
onChange={(value: string) => {
48-
change(v.field, value);
49-
innerValidate();
50-
}}
51-
value={store[v.field]}
52-
{...v.attr}
53-
/>
54-
);
55-
}
56-
if (v.type === 'radio') {
57-
return options.map((item, idx) => (
58-
<Radio
59-
key={idx}
60-
checked={item.value === store[v.field]}
61-
onPress={() => {
62-
change(v.field, item.value);
63-
innerValidate();
64-
}}
65-
{...v.attr}
66-
>
67-
{item.label}
68-
</Radio>
69-
));
70-
}
71-
if (v.type === 'checkBox') {
72-
return options.map((item, idx) => {
73-
const values = store[v.field] || [];
74-
return (
75-
<CheckBox
76-
key={idx}
77-
checked={values.includes(item.value)}
78-
onChange={() => {
79-
let data = store[v.field] || [];
80-
if (!data.includes(item.value)) {
81-
data.push(item.value);
82-
} else {
83-
const idx = data.findIndex((v: KeyType) => v === item.value);
84-
data.splice(idx, 1);
85-
}
86-
change(v.field, data);
87-
innerValidate();
88-
}}
89-
{...v.attr}
90-
>
91-
{item.label}
92-
</CheckBox>
93-
);
94-
});
95-
}
96-
if (v.type === 'rate') {
97-
return (
98-
<Rating
99-
onPress={(number) => {
100-
change(v.field, number);
101-
innerValidate();
102-
}}
103-
{...v.attr}
104-
/>
105-
);
106-
}
107-
if (v.type === 'switch') {
108-
return (
109-
<Switch
110-
checked={store[v.field]}
111-
onValueChange={(value) => {
112-
change(v.field, !store[v.field]);
113-
innerValidate();
114-
}}
115-
{...v.attr}
116-
/>
117-
);
118-
}
119-
if (v.type === 'search') {
120-
return (
121-
<SearchBar
122-
options={options}
123-
onChange={(value) => {
124-
change(v.field, value);
125-
innerValidate();
126-
}}
127-
contentStyle={{ paddingHorizontal: 0 }}
128-
{...v.attr}
129-
/>
130-
);
131-
}
132-
if (v.type === 'datePicker') {
133-
return <FormDatePicker value={store[v.field]} ok={(value) => change(v.field, value)} {...v.attr} />;
134-
}
135-
if (v.type === 'stepper') {
136-
return (
137-
<Stepper
138-
value={store[v.field]}
139-
onChange={(value) => {
140-
change(v.field, value);
141-
innerValidate();
142-
}}
143-
{...v.attr}
144-
/>
145-
);
146-
}
147-
if (v.type === 'slider') {
148-
return (
149-
<Slider
150-
value={store[v.field]}
151-
onChange={(value) => {
152-
change(v.field, value);
153-
innerValidate();
154-
}}
155-
{...v.attr}
156-
/>
157-
);
158-
}
15923
if (v.type === 'cardList') {
16024
return <FormList formListValue={v} />;
16125
}
16226
// 自定义组件
16327
if (!isObjectEmpty(customComponentList) && Object.keys(customComponentList).includes(v.type)) {
16428
return React.isValidElement(customComponentList[v.type])
16529
? React.cloneElement(customComponentList[v.type], {
30+
...v,
16631
...v.attr,
16732
value: store[v.field],
16833
onChange: (value: unknown) => {

0 commit comments

Comments
 (0)