我一直在尝试实现API,用Antd自动填充简单地址表单的字段,但到目前为止,在选择了一个地方后,字段不会按照我想要的方式填充。
我正在使用包react-google-autocomplete
成功地得到我想要的。
为了进行测试,我一直专注于只使用1个字段,即city
字段。
现在,我的表单被分解为两个元素。
新表单.tsx
const NewForm = (props: Props) => {
const [form] = Form.useForm();
const formRef = useRef<any>(null);
const onFinish = async (values: any) => {
const newAddressData: NewAddressInput = {
name: values.name?.toUpperCase(),
company: values.company?.toUpperCase(),
street1: values.street1.toUpperCase(),
street2: values.street2?.toUpperCase(),
city: values.city.toUpperCase(),
state: values.state.toUpperCase(),
zip: values.zip.toUpperCase(),
country: values.country.toUpperCase(),
phone: values.phone,
notes: values.notes,
};
const onFinishFailed = (errorInfo: any) => {
console.log('Failed:', errorInfo);
if (errorInfo.errorFields.length > 0) {
errorInfo.errorFields.map((field: { errors: string[]; }, index: any) => {
toast.error(field.errors[0] as string);
});
}
};
useEffect(() => {
console.log('form values in useEffect', form.getFieldValue('city'));
}, [form]);
console.log('form values', form.getFieldValue('city'));
return (
<Dashboard>
<Form
ref={formRef}
form={form}
name="newClientForm"
labelCol={{ span: 3 }}
wrapperCol={{ span: 22 }}
initialValues={{ remember: true }}
onFinish={onFinish}
onFinishFailed={onFinishFailed}
autoComplete="off"
className={styles.createClientForm}
layout="horizontal"
onValuesChange={(changed, all) => console.log('values change', changed, all)}
onFieldsChange={(first, second) => console.log('fields change', first, second)}
fields={[
{
name: 'city',
value: form.getFieldValue('city')
}
]}
>
<h2>Create a New Client</h2>
<Divider />
<CreateAddressFields />
<Form.Item
style={{ textAlign: 'center' }}
// wrapperCol={{ offset: 4, span: 16 }}
>
<Button
type="primary"
htmlType="submit">
Submit
</Button>
</Form.Item>
</Form>
</Dashboard>
);
};
创建地址字段.tsx
function CreateAddressFields({ }: Props) {
const [foundAddress, setFoundAddress] = useState<NewAddressInput | null>(null);
const [city, setCity] = useState<string | null>(null);
const inputRef = useRef<any>(null);
const options = {
componentRestrictions: { country: ["ca", "us"] },
fields: ["address_components", "geometry", "icon", "name"],
types: ["address"]
};
// inputRef.current.focus();
const { ref, autocompleteRef } = usePlacesWidget({
apiKey: PLACES_API_KEY,
onPlaceSelected: (place, inputRef, something) => {
console.log('place selected', place);
const address = place.address_components;
let { street1, street2, city, state, zip, country }: NewAddressInput = {
street1: '',
street2: '',
city: '',
zip: '',
state: '',
country: ''
};
if (address) {
console.log('going through found address');
for (const component of address) {
const type = component.types[0];
switch (type) {
case "street_number":
street1 = `${component.long_name} ${street1}`;
break;
case "route": {
street1 += component.short_name;
break;
}
case "postal_code": {
zip = `${component.long_name}${zip}`;
break;
}
case "locality":
city = `${component.long_name}${city}`;
break;
case "administrative_area_level_1": {
state = `${component.short_name}${state}`;
break;
}
case "country":
country = `${component.short_name}${country}`;
break;
default:
break;
}
}
setFoundAddress({ street1, street2, city, state, zip, country });
console.log('results', { street1, street2, city, state, zip, country });
}
},
options
});
const handleChange = (event: any) => {
console.log('name', event.target.name);
const name = event.target.name;
console.log('value', event.target.value);
const value = event.target.value;
setFoundAddress({ ...foundAddress!, [event.target.name]: event.target.value });
if (name === 'city') {
setCity(value);
}
};
return (
<>
<Form.Item
label="Name: "
name="name"
rules={[{ required: true, message: 'Please input your name!' }]}>
<Input
// onChange={handleChange}
/>
</Form.Item>
<Form.Item
label="Company: "
name="company">
<Input />
</Form.Item>
<Form.Item
label="Street Info 1:"
name="street1"
rules={[{ required: true, message: 'Please input your street1!' }]}>
<Input
placeholder=''
ref={(c) => {
inputRef.current = c;
if (c) ref.current = c.input;
}}
// ref={inputRef}
/>
</Form.Item>
<Form.Item
label="Street Info 2:"
name="street2">
<Input />
</Form.Item>
<Form.Item
label="City:"
name="city"
// initialValue={foundAddress?.city ? foundAddress.city : ''}
// getValueFromEvent={handleChange}
getValueProps={(v) => {
return ({ name: 'city', value: v });
}}
rules={[{ required: true, message: 'Please input your city!' }]}>
<Input
onChange={handleChange}
value={city!
// ? foundAddress.city : ''
}
// placeholder={foundAddress?.city}
/>
</Form.Item>
{/* <input
name={"city"}
value={foundAddress?.city}
placeholder={"City"}
onChange={handleChange}
/> */}
<Form.Item
label="State:"
name="state"
rules={[{ required: true, message: 'Please input your state!' }]}>
<Input />
</Form.Item>
<Form.Item
label="Zip:"
name="zip"
rules={[{ required: true, message: 'Please input your zip!' }]}>
<Input />
</Form.Item>
{/* {countriesList && ( */}
<Form.Item
label="Country:"
name="country"
rules={[{ required: true, message: 'Please choose your country!' }]}>
<Input />
</Form.Item>
{/* )} */}
<Form.Item
label="Phone:"
name="phone"
rules={[{ required: true, message: 'Please input your phone number!' }]}>
<Input />
</Form.Item>
<Form.Item
label="Notes:"
name="notes">
<Input />
</Form.Item>
</>
在street1
字段中键入时触发建议。一旦选择了一个地点,它就成功地设置了状态变量foundAddress
。但是其他字段(在本测试用例中为city)都不会用所选值填充。
我试过很多方法:
- 使用
Form.Item
的 prop ,例如initialValue
、getValueFromEvent
、getValueProps
。 - 在
Input
组件上添加 prop - 使用
Form
组件的 prop :一米十氮一x一米十一氮一x一米十二氮一x - 为
city
字段创建唯一的状态变量。
该字段永远不会更新。
另一方面,如果我使用简单的<input>
,我测试并获得了状态变量填充时的值,而且,如果我将<Input>
的placeholder
填充为placeholder={foundAddress?.city}
,则在正确选择地址后,它确实如预期的那样工作。
在这个Antd表单的值处理中,我做错了什么?
1条答案
按热度按时间oalqel3c1#
使用
form.setFieldValue("key", value)
更新表单域