Umbro
Umbro

Reputation: 2204

Setting the default value inside the input field in the antd library after calling the function in useEffect

I have the loadProfile function that I want to call in useEffect. If the loadProfile function is called within useEffect, the name Mario should be displayed inside the input name field. How can I set the default value in the antd library inside input? I try to use defaultValue but the input field remains empty.

Example here: https://stackblitz.com/edit/react-311hn1

const App = () => {

    const [values, setValues] = useState({
        role: '',
        name: '',
        email: '',
        password: '',
        buttonText: 'Submit'
    });

    useEffect(() => {
        loadProfile();
    }, []);

    const loadProfile = () => { 
        setValues({...values, role, name="Mario", email});
    }

    const {role, name, email, buttonText} = values;



    const updateForm = () => (
        <Form
            {...layout}
            name="basic"
            initialValues={{
                remember: true,
                name: name
            }}
        >
            <Form.Item
                label= 'Name'
                name='name'
                rules={[
                    {
                        required: true,
                        message: 'Please input your name!',
                    },
                ]}
            >
                <Input 
                    defaultValue= {name}
                />
            </Form.Item>

            <Form.Item
                label="Email"
                name="email"
                value={email}
                rules={[
                    {
                        type: 'email',
                        required: true,
                        message: 'Please input your email!',
                    },
                ]}
            >
                <Input 
                />
            </Form.Item>

            <Form.Item {...tailLayout}>
                <Button type="primary" htmlType="submit">
                    {buttonText}
                </Button>
            </Form.Item>
        </Form>
    );

    return (
        <>
            <Row>
                <Col span={24} style={{textAlign: 'center'}}>
                  <h1>Private</h1>
                  <p>Update Form</p>
                </Col>
            </Row>
                {updateForm()}
        </>
    );
};

Upvotes: 7

Views: 22372

Answers (1)

Diesel
Diesel

Reputation: 5355

You have to make three changes to your code. This is a working component, I also extracted your component and put the appropriate state in there. I also made it functional.

https://stackblitz.com/edit/react-tlm1qg

First change

setValues({...values, role, name="Mario", email});

to

setValues({...values, name: "Mario"});

This will properly set the state.

Second change:

Next, you should notice that if you set defaultValue="test123" it still won't work, something is up. Remove name from Form.Item and boom it works. test123 shows up. But if you put values.name in there, it still doesn't work!

Third Change:

That's because defaultValue only sets that value right when the component is created, not on mount. So you have to use value={values.name} and it will set that value once on mount per your useEffect

In the demo component I also added a change handler for you so the user can type in there, if you wanted that.


If you look at the FAQ for Ant Design it says:

Components inside Form.Item with name property will turn into controlled mode, which makes defaultValue not work anymore. Please try initialValues of Form to set default value.

Ant Design is taking over control - so you don't have to set value={name} and onChange.

You want to set the values AFTER the component is created. So to do that you need

  const [form] = Form.useForm();
  
  React.useEffect(() => {
    form.setFieldsValue({
      username: 'Mario',
    });
  }, []);

and in you Form make sure you add:

    <Form
        {...layout}
        name="basic"
        initialValues={{
            remember: true,
        }}
        form={form} // Add this!
    >

I updated my online example.

Big picture - when you want to set the value after creation, use this hook and form.setFieldsValue

Upvotes: 13

Related Questions