I have Antd dropdown component with input field. when i press + and - buttons it populate the values in the input field, but when i click on submit i get value of undefined. i Have tried to nest Form.Item one level below but it is undefined again.
my component looks like this
const PeopleNumber = () => {
const [adult, setAdult] = useState(0);
const [child, setChild] = useState(0);
const [passcount, setPasscount] = useState('Adult (0), Child(0)');
const menu = () => {
return (
<>
<div className="adult-child-drawer">
<div className="adult-child-button">
Adult
<span style={{float: 'right'}}>
<PlusCircleOutlined onClick={addAdult} style={{margin: '8px'}}/>
{adult}
<MinusCircleOutlined onClick={removeAdult} style={{margin: '8px'}}/>
</span>
</div>
<div className="adult-child-button">
Child
<span style={{float: 'right'}}>
<PlusCircleOutlined onClick={addChild} style={{margin: '8px'}}/>
{child}
<MinusCircleOutlined onClick={removeChild} style={{margin: '8px'}}/>
</span>
</div>
</div>
</>
);
};
useEffect(() => {
setPasscount(`Adult (${adult}), Child(${child})`);
}, [adult, child]);
const addAdult = () => {
setAdult((prevAdult) => prevAdult + 1);
};
const removeAdult = () => {
if (adult > 0) setAdult((prevAdult) => prevAdult - 1);
};
const addChild = () => {
setChild((prevChild) => prevChild + 1);
};
const removeChild = () => {
if (child > 0) setChild((prevChild) => prevChild - 1);
};
return (
<>
<div className="people-form">
<Form.Item name='people'>
<Dropdown overlay={menu} trigger={['click']}>
<Input value={(adult || child > 0)?passcount:''} placeholder={passcount} style={ (adult || child !== 0)?{color:'#5A5B5B'}: {color:'#B3B4B5'}} bordered={false}/>
</Dropdown>
</Form.Item>
</div>
</>
);
};
export default PeopleNumber;
PeopleNumber component is added to the parent component which submits. After submit i get values of all other components except PeopleNumber.Please help.
const onFinish = (value) => {
console.log('values are:', value)
}
<Form onFinish={onFinish} form={form}>
<From/>
<To/>
<Date/>
<PeopleNumber/>
<Button htmlType='submit
Search
</Button>
<Form/>
Complete Code
Changes:
Set the people
value in useEffect using form
Need To Pass form from Parent Component
to People Number Component
import { useEffect, useState } from 'react';
import { Button, Dropdown, Form, Input } from 'antd';
import { MinusCircleOutlined, PlusCircleOutlined } from '@ant-design/icons';
const PeopleNumber = (props) => {
const { form } = props;
const [adult, setAdult] = useState(0);
const [child, setChild] = useState(0);
const [passcount, setPasscount] = useState('Adult (0), Child(0)');
const menu = () => {
return (
<>
<div className='adult-child-drawer'>
<div className='adult-child-button'>
Adult
<span style={{ float: 'right' }}>
<PlusCircleOutlined onClick={addAdult} style={{ margin: '8px' }} />
{adult}
<MinusCircleOutlined onClick={removeAdult} style={{ margin: '8px' }} />
</span>
</div>
<div className='adult-child-button'>
Child
<span style={{ float: 'right' }}>
<PlusCircleOutlined onClick={addChild} style={{ margin: '8px' }} />
{child}
<MinusCircleOutlined onClick={removeChild} style={{ margin: '8px' }} />
</span>
</div>
</div>
</>
);
};
useEffect(() => {
let value = `Adult (${adult}), Child(${child})`;
setPasscount(value);
form.setFieldsValue({ people: value });
}, [adult, child, form]);
const addAdult = () => {
setAdult((prevAdult) => prevAdult + 1);
};
const removeAdult = () => {
if (adult > 0) setAdult((prevAdult) => prevAdult - 1);
};
const addChild = () => {
setChild((prevChild) => prevChild + 1);
};
const removeChild = () => {
if (child > 0) setChild((prevChild) => prevChild - 1);
};
return (
<>
<div className='people-form'>
<Form.Item name='people'>
<Dropdown overlay={menu} trigger={['click']}>
<Input
value={adult || child > 0 ? passcount : ''}
placeholder={passcount}
style={adult || child !== 0 ? { color: '#5A5B5B' } : { color: '#B3B4B5' }}
bordered={false}
/>
</Dropdown>
</Form.Item>
</div>
</>
);
};
const App = () => {
const [form] = Form.useForm();
const onFinish = (value) => {
console.log('values are:', value);
};
return (
<Form form={form} onFinish={onFinish}>
<PeopleNumber form={form} />
<Button htmlType='submit' type='primary'>
Submit
</Button>
</Form>
);
};
export default App;
Solution: If you want the same value that you show in input as placeholder, you can replace your useEffect with the following code
useEffect(() => {
let value = `Adult (${adult}), Child(${child})`;
setPasscount(value);
form.setFieldsValue({ people: value });
}, [adult, child, form]);
TLDR:
<Form.Item name='people'>
<Dropdown overlay={menu} trigger={['click']}>
<Input value={(adult || child > 0)?passcount:''} placeholder={passcount} style={ (adult || child !== 0)?{color:'#5A5B5B'}: {color:'#B3B4B5'}} bordered={false}/>
</Dropdown>
</Form.Item>
If you try to type in Input Field, it will not work as <Form.Item> requires a single & direct field in order to make work. You are getting undefined just because you wrapped Input Field with Dropdown and <Form.Item>.
But if you wrap <Form.Item> with Dropdown, now you can type in input field.
Now your question will be if you are setting the value of Input Field, why it doesn't show up after submitting the form even you move dropdown outside the <Form.Item>?
Answer: Since you are using antd form hook and it controls the Input Field which is wrapped in <Form.Item> automatically. Since you just pass the value but did not set the value using form.setFieldsValue({people: someValue
}). That's why it doesn't show up when you submit the form.