reactjs 如何根据状态变量更新Antd的表单项输入值和内容?

jgovgodb  于 2023-03-01  发布在  React
关注(0)|答案(1)|浏览(254)

我一直在尝试实现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 ,例如initialValuegetValueFromEventgetValueProps
  • Input组件上添加 prop
  • 使用Form组件的 prop :一米十氮一x一米十一氮一x一米十二氮一x
  • city字段创建唯一的状态变量。

该字段永远不会更新。
另一方面,如果我使用简单的<input>,我测试并获得了状态变量填充时的值,而且,如果我将<Input>placeholder填充为placeholder={foundAddress?.city},则在正确选择地址后,它确实如预期的那样工作。
在这个Antd表单的值处理中,我做错了什么?

oalqel3c

oalqel3c1#

使用form.setFieldValue("key", value)更新表单域

相关问题