I am trying to add Select All / Unselect All to React Antd's 'SELECT' component.
My code
const models = ['A4', 'A6', 'A8', 'A1', 'Q3', 'Q5'];
const [selected, setSelected] = useState({
models: [],
});
console.log('selected', selected);
const handleModelSelect = (option) => {
if (option === 'all') {
if (selected.models.length === models.length) {
setSelected((prev) => ({ ...prev, models: [] }));
} else {
setSelected((prev) => ({ ...prev, models }));
}
} else {
setSelected((prev) => ({ ...prev, models: uniq([...prev.models, option]) }));
}
};
return
(<Form>
<Form.Item
name="model"
style={{ display: 'inline-block', width: 'calc(33% - 8px)' }}
>
<Select mode="multiple" placeholder="Models" value={selected.models} onSelect={handleModelSelect}>
<Option value="all">Select all</Option>
{map(models, model => <Option value={model} key={model}>{model}</Option>)}
</Select>
</Form.Item>
</Form>)
I see that I do get everything selected & unselected in the "selected.models", however the issue is that the Select component visually does NOT update itself, meaning it stays with things I have selected/unselected.
Really weird behavior.
I am trying to add Select All / Unselect All to React Antd's 'SELECT' component.
My code
const models = ['A4', 'A6', 'A8', 'A1', 'Q3', 'Q5'];
const [selected, setSelected] = useState({
models: [],
});
console.log('selected', selected);
const handleModelSelect = (option) => {
if (option === 'all') {
if (selected.models.length === models.length) {
setSelected((prev) => ({ ...prev, models: [] }));
} else {
setSelected((prev) => ({ ...prev, models }));
}
} else {
setSelected((prev) => ({ ...prev, models: uniq([...prev.models, option]) }));
}
};
return
(<Form>
<Form.Item
name="model"
style={{ display: 'inline-block', width: 'calc(33% - 8px)' }}
>
<Select mode="multiple" placeholder="Models" value={selected.models} onSelect={handleModelSelect}>
<Option value="all">Select all</Option>
{map(models, model => <Option value={model} key={model}>{model}</Option>)}
</Select>
</Form.Item>
</Form>)
I see that I do get everything selected & unselected in the "selected.models", however the issue is that the Select component visually does NOT update itself, meaning it stays with things I have selected/unselected.
Really weird behavior.
Share Improve this question asked Apr 4, 2020 at 13:27 AlexAlex 1,4204 gold badges22 silver badges39 bronze badges 1- minimal reproducible example, maybe an online demo would be great for others trying to find out the problem you are facing quickly – keikai Commented Apr 4, 2020 at 13:33
5 Answers
Reset to default 9The issue was with using Antd's Form & Form.item along with Select. Code works perfectly fine without the Form
Alex answer is correct. For anyone who need Form.item as parent for Select - it is possible with custom form components. Just create your custom component that render antd Select. And paste your component as only child to Form.item (without any nested elements or wrappers)
<Form.Item>
<MySelect />
</Form.Item>
Your custom component will automatically receive value and onChange as props. And you can also pass in additional your own props to your custom component. For example field name or data - an array of options for select.
If you define a name prop on a Form.Item, it intercepts a value prop of a child component. You should use a form methods to manage a data state of the child component (more info below a props list). If you want use the value prop don't define the name prop on the Form.Item, or don't wrap it in a Form component, but in this case you can't use the form stuff like validation.
Because the models
variable is unchanged. You could apply the below two changes:
One
const models = ['A4', 'A6', 'A8', 'A1', 'Q3', 'Q5'];
const [selected, setSelected] = useState({
// Initial state
models,
});
Two
// Get models from `selected`
{map(selected.models, model => <Option value={model} key={model}>{model}</Option>)}
I encountered a similar issue when using a custom form wrapper around the Select component. If you remove the name attribute from the Form.Item element, the Select component renders properly. However, if you need to retain the name attribute to access form values and set initial values, avoid setting the value prop directly on Select. Instead, use form.setFieldValue("model", ) to control the selected value dynamically. If you implement this change, there is no need to use the value or onchange props as these will be handled automatically.