I have two antd select fields in a row and a + icon to add another row with two dropdowns as shown in the image.
On click of the first dropdown value, related data should be displayed in dropdown2, and click on + icon it will add two more dropdowns in the second row and respectively and the requirement is the same, onlick of 2nd row first dropdown value. related values will be displayed in the 2nd row 2nd drop-down field.
Issue:
2nd drop-down values are always the same for both rows. When I select the 2nd-row first dropdown value, related values show in 2nd row 2nd dropdown but the same values reflect in the first row second dropdown.
Below my code snippet and I am using antd Form to achieve this. For single row drop-downs it works as expected, but when I add another row by clicking on + icon, an issue occurs. Is there any other approach to implement this?
The code snippet I have added may not work in some environments.
import React, { useRef, useEffect, useState } from "react";
import { Form, Select, Col, Row, Button, Checkbox } from "antd/lib";
import { PlusOutlined, MinusOutlined } from "#ant-design/icons";
const { Option } = Select;
const DropdownComponent = (props) => {
const addBtnRef = useRef(null);
const [dropDownOneData, setDropDownOneData] = useState([]);
const [dropDownTwoData, setDropDownTwoData] = useState([]);
const [dropDownOneValue, setDropDownOneValue] = useState("");
const dropDownOneTwoValues: [
[
{
dropDownOne: {
key: "test_t";
value: "test";
};
dropDownTwo: [
{
key: "key1";
value: "Value1";
},
{
key: "key2";
value: "Value2";
}
];
}
],
[
{
dropDownOne: {
key: "test_t1";
value: "test1";
};
dropDownTwo: [
{
key: "key3";
value: "Value3";
},
{
key: "key4";
value: "Value4";
}
];
}
]
];
useEffect(() => {
addBtnRef.current.click();
// set dropdownone values
const dropDownOneData = dropDownOneTwoValues?.map(
(searchField) => searchField[0].dropDownOne
);
setDropDownOneData(dropDownOneData);
}, []);
useEffect(() => {
// set related dropDownTwo values on selected dropdownOne value
const dropDownTwoValues = dropDownOneTwoValues
.flat()
.filter((values) => values.dropDownOne.key === dropDownOneValue)
.flatMap((value) => value.dropDownTwo);
setDropDownTwoData(dropDownTwoValues);
}, [dropDownOneValue]);
const handleDropDownOne = (value) => {
setDropDownOneValue(value);
};
function renderDropDownValues(options) {
return options.map((option) => {
if (option.key && option.value) {
return (
<Option
key={option.key}
value={option.key}
disabled={option.disabled}
>
{option.value}
</Option>
);
}
return (
<Option key={option} value={option}>
{option}
</Option>
);
});
}
return (
<>
<Row>
<Col>
<Form.List>
{(fields, { add, remove }) => {
{
console.log("fields...", fields);
}
return (
<div
className="border"
style={{
padding: "20px",
marginBottom: "25px",
marginTop: "-30px"
}}
>
{fields.map((value, index) => {
return (
<Row key={index} style={{ marginBottom: 8 }}>
<Col>
<Form.Item
rules={[
{ required: true, message: "Select a value" }
]}
name={value.Name}
>
<Select
key={index}
className="w-100"
showSearch={true}
optionFilterProp="children"
filterOption={(input, option) =>
option?.children
.toLowerCase()
.includes(input.toLowerCase())
}
placeholder="Select"
onChange={(value) => handleDropDownOne(value)}
value={dropDownOneValue}
>
{renderDropDownValues(dropDownOneData)}
</Select>
</Form.Item>
</Col>
<Col>
<Form.Item
rules={[
{ required: true, message: "Select a value" }
]}
name={value.name}
>
<Select
className="w-100"
showSearch={true}
optionFilterProp="children"
filterOption={(input, option) =>
option?.children
.toLowerCase()
.includes(input.toLowerCase())
}
placeholder="Select"
>
{renderDropDownValues(dropDownTwoData)}
</Select>
</Form.Item>
</Col>
</Row>
);
})}
<Row justify="end">
<Col>
<Form.Item>
<Button
ref={addBtnRef}
shape="circle"
size="small"
className="center"
data-testid="add-clause-btn"
icon={
<PlusOutlined
className="primary-color"
style={{ marginTop: "1px" }}
/>
}
onClick={() => {
add();
}}
/>
</Form.Item>
</Col>
</Row>
</div>
);
}}
</Form.List>
)
</Col>
</Row>
</>
);
};
export default DropdownComponent;
You need to have unique Form.Item name for every row.
Try this,
name={[index, value.Name]}
and provide a name for Form.List also, name={"something"}
Related
I try to build a site similar to wikipedia and its Edit functionality trouble me
think I send some data from DB like this
{
"post":[
{"title":"SOME TITLE","date":"20-12-2021"},
{"title":"SOME TITLE 2","date":"20-11-2021"}
]
}
with this data I need to show data to user and as well option to edit as well
so this means title and date are in some sort state variable I guess
how to achieve this I don't know I make question right but please consider wikipedia edit feature as example
how to implement it in react
Thanks
import { Form, Input, Button, Col, Row } from "antd";
import { PlusOutlined } from "#ant-design/icons";
const minusStyle = {
position: "relative",
margin: "0 8px",
color: "#999",
fontSize: "24px",
cursor: "pointer",
transition: "all 0.3s",
};
const PanditComponent = ({
panditNamez,
panditContactz,
onChangeSetPanditName,
onChangeSetPanditContact,
}) => {
console.log(panditContactz,panditNamez,onChangeSetPanditContact,onChangeSetPanditName)
return (
<Form style={{ marginTop: "8px" }}>
<Row>
<Col span={11}>
<Form.Item onChange={onChangeSetPanditName}>
<Input value={panditNamez} placeholder="Pandit Name"></Input>
</Form.Item>
</Col>
<Col span={11}>
<Form.Item onChange={onChangeSetPanditContact}>
<Input value={panditContactz} placeholder="Pandit Contact"></Input>
</Form.Item>
</Col>
<Col span={2}>
<Button icon={<PlusOutlined />} style={minusStyle}></Button>
</Col>
</Row>
</Form>
);
};
export default PanditComponent;
and this code to render the elements
data.pandit.map((p, index) => (
<PanditComponent
key={index}
panditNamez={panditDBItems[index]["name"]}
panditContactz={panditDBItems[index]["contact"]}
onChangeSetPanditName={(e) =>
// setPanditDBItems([{ name: "AAAAA", contact: "1234" }])
setPanditDBItems([{...panditDBItems,}])
}
onChangeSetPanditContact={(e) => console.log(e.target.value)}
/>
))
: null}
OK I solve this
if we break this question into simple words how to update state of array of objects like
panditDBItems = [{name:"aa",contact:12},{name:"b",contact:21}]
we can use do something
panditDBItems.map((p, index) => (
<PanditComponent
key={index}
panditNamez={panditDBItems[index]["name"]}
panditContactz={panditDBItems[index]["contact"]}
onChangeSetPanditName={(e) => {
let newPanditDBItems = [...panditDBItems];
newPanditDBItems[index]["name"] = e.target.value;
setPanditDBItems(newPanditDBItems);
}}
onChangeSetPanditContact={(e) => {
let newPanditDBItems = [...panditDBItems];
newPanditDBItems[index]["contact"] = e.target.value;
setPanditDBItems(newPanditDBItems);
}}
/>
)
I have a multiple recepient email and multiple checkbox column
I want to get each recepient email and checkbox values on submit.I am getting recepient emails on submit but no checkbox values. Kindly help
The form looks like this.
Here is my code
export default function ShareReportView(props) {
const [recipientEmails, updateRecicpientEmails] = useState({});
const handleInputChange = (e, name) => {
updateRecicpientEmails((prevState) => ({
...prevState,
[name]: e.target.value,
}));
};
const extratEmailList = (emailsList) => {
if (!emailsList || !Object.keys(emailsList).length) {
return;
}
console.log('obj email list',Object.values(emailsList))
return Object.values(emailsList);
};
const handlepermission = () => {
};
function sendEmail(recipientEmailsList) {
const rEmails = extratEmailList(recipientEmailsList);
console.log(rEmails);#prints all emails here
#here i want to get all checkbox values here on submit
}
return (
<div className="container">
{[...Array(count)].map((val, index) => (
<div key={index} className={`${styles["textField"]}`}>
<div style={{ float: "left" }}>
<Box
component="form"
sx={{
"& > :not(style)": { marginRight: 4, width: "31ch" },
}}
noValidate
autoComplete="off"
>
{" "}
<FormControl variant="standard">
<InputLabel
htmlFor="component-simple">
Recipient E mail
</InputLabel>
<Input
id="component-simple"
onChange={(event) =>
handleInputChange(
event,
`recipient_email_${index++}`,
false
)
}
name={`recipient_email_${index++}`}
key={`recipient_email_${index++}`}
disableUnderline={true}
/>
</FormControl>
<FormControlLabel
control={
<Checkbox
color="default"
onClick={() => {
handlepermission(`${index++}`);
}}
/>
}
label="Allow user to perfrom action"
name={`allow_user_edit_${index++}`}
/>
</Box>
</div>
</div>
))}
<div className="btn">
<button
className={`${styles.send}`}
onClick={() => sendEmail(recipientEmails)}
>
SEND
</button>
</div>
</div>
)}
I am not on my computer but following should work
export default function ShareReportView(props) {
const [recipientEmails, updateRecicpientEmails] = useState([]);
const handleEmailChange = (e, index) => {
let temp = [...recipientEmails]
let tempObj = {...temp[index]}
tempObj.email = e.target.value
temp.splice(index, 1, tempObj)
updateRecicpientEmails(temp)
};
const handlePermissionChange = (e, index) => {
let temp = [...recipientEmails]
let tempObj = {...temp[index]}
tempObj.permission = e.target.value
temp.splice(index, 1, tempObj)
updateRecicpientEmails(temp)
};
function sendEmail(recipientEmailsList) {
recipientEmails.forEach(e => {
console.log(e.email, e.permission)
})
}
return (
<div className="container">
{[...Array(count)].map((val, index) => (
<div key={index} className={`${styles["textField"]}`}>
<div style={{ float: "left" }}>
<Box
component="form"
sx={{
"& > :not(style)": { marginRight: 4, width: "31ch" },
}}
noValidate
autoComplete="off"
>
{" "}
<FormControl variant="standard">
<InputLabel
htmlFor="component-simple">
Recipient E mail
</InputLabel>
<Input
id="component-simple"
onChange={(event) =>
handleEmailChange(
event,
index
)
}
name={`recipient_email_${index++}`}
key={`recipient_email_${index++}`}
disableUnderline={true}
/>
</FormControl>
<FormControlLabel
control={
<Checkbox
color="default"
onClick={(e) => {
handlePermissionChange(e, index);
}}
/>
}
label="Allow user to perfrom action"
name={`allow_user_edit_${index++}`}
/>
</Box>
</div>
</div>
))}
<div className="btn">
<button
className={`${styles.send}`}
onClick={() => sendEmail(recipientEmails)}
>
SEND
</button>
</div>
</div>
)}
Let me know if you feel any issues, will be happy to help you, you should also change the logic of add and remove entries button. On add button just add a new object with empty values in recipientEmails list. and use your map function in render on recipientEmails.
Edit # 1
function addNewEntry(){ //call this on add new entry button
let temp = [...recipientEmails]
temp.push({
email: '',
permission: false
})
updateRecicpientEmails(temp)
}
you can use addNewEntry for adding new row. but now your will have to edit your render function something like this
replace {[...Array(count)].map((val, index) => (
with {recipientEmails.map((val, index) => (
in your return staement
You need to save multiple values on the same object per recipient, I did this change on your handleInputChange function, now it creates an object per recipient
const handleInputChange = (e, name) => {
updateRecicpientEmails((prevState) => ({
...prevState,
[name]: {
email: e.target.value
}
}));
};
and I call it like this
handleInputChange(event, `recipient_${index}`, false)
removed _email from there.
And for the handle permission, just add a new property to the recipient object with the checkbox value
const handlepermission = (index, value) => {
updateRecicpientEmails((currentRecipients) => ({
...currentRecipients,
[index]: {
...currentRecipients[index],
allow: value
}
}));
};
this function runs on input change, so just add this to prop to the input:
onChange={({ target: { checked } }) => {
handlepermission(`recipient_${index}`, checked);
}}
To be honest is easier if you use the native form submit handler and FormData API, here is an example:
https://codesandbox.io/s/formdata-api-example-xkvi8
I would like to populate an input value depending on the selected name before.
For exemple, if I select "FRANCILIENNE CONSEIL" I would like the right IBAN associated to be the value of the input.
I tried several things without success.
Here is a stackblitz of my code : https://stackblitz.com/edit/react-rc3me7
you can create some states to handle both select option & input for starter. Then update them through your handleChangeBeneficiary function.
in Option, would be ideal if you use a unique variable like beneficiaryId instead of name unless your name here also unique.
you can see the working code here: https://stackblitz.com/edit/react-rc3me7-gr3fmu
import React, { useState } from 'react'
const Demo = () => {
const [beneficiary, setbeneficiary] = useState()
const [iban, setiban] = useState()
const handleChangeBeneficiary = (value) => {
console.log(`selected ${value}`);
setbeneficiary(value)
// get selected iban
const selected = beneficiaries?.find(item => item?.beneficiaryId == value)
setiban(selected?.iban)
};
const onFinish = (values) => {
console.log('Success:', values);
};
const onFinishFailed = (errorInfo) => {
console.log('Failed:', errorInfo);
};
const beneficiaries = [
{
iban: 'FR76167LQSDKJLKSQJ86538089',
name: 'FRANCILIENNE CONSEIL',
bic: 'TRZOFR21XXX',
beneficiaryId: '60c38ddf-63f9-4589-888b-27b7e1a50e53',
},
{
iban: 'FR291001DSKLFJSLKJ8633Z17',
name: 'MR NAMLA EMAD',
bic: 'PSSTFRPPCNE',
beneficiaryId: '60a11891-81ba-4ab2-9b92-ce4f461c2d50',
},
];
return (
<Form
{...layout}
name="test"
onFinish={onFinish}
onFinishFailed={onFinishFailed}
autoComplete="off"
>
<Form.Item label="Nom du bénéficiare" name="benef">
<Select
// defaultValue=""
value={beneficiary}
style={{ width: 300, marginBottom: 20 }}
onChange={handleChangeBeneficiary}
>
{beneficiaries.map((nom) => (
<Option value={nom.beneficiaryId}> {nom.name} </Option>
))}
</Select>
</Form.Item>
<Form.Item label="IBAN" name="iban">
<Input
// autoComplete="off"
style={{ marginBottom: 20 }}
placeholder={iban}
disabled/>
</Form.Item>
<Form.Item wrapperCol={{ ...layout.wrapperCol, offset: 8 }}>
<Button type="primary" htmlType="submit">
Submit
</Button>
</Form.Item>
</Form>
);
};
You can update the value of IBAN as well. Please try the below code.
import React, {useState} from 'react';
import ReactDOM from 'react-dom';
import 'antd/dist/antd.css';
import './index.css';
import { Form, Input, InputNumber, Button, Select } from 'antd';
const layout = {
labelCol: {
span: 8,
},
wrapperCol: {
span: 16,
},
};
/* eslint-disable no-template-curly-in-string */
const { Option } = Select;
/* eslint-enable no-template-curly-in-string */
const Demo = () => {
const [iban,setValue] =useState('')
const handleChangeBeneficiary = (value) => {
console.log(`selected ${value}`);
const ben= beneficiaries.filter((b)=>b.name===value)
setValue(value)
};
const onFinish = (values) => {
console.log('Success:', values);
};
const onFinishFailed = (errorInfo) => {
console.log('Failed:', errorInfo);
};
const beneficiaries = [
{
iban: 'FR76167LQSDKJLKSQJ86538089',
name: 'FRANCILIENNE CONSEIL',
bic: 'TRZOFR21XXX',
beneficiaryId: '60c38ddf-63f9-4589-888b-27b7e1a50e53',
},
{
iban: 'FR291001DSKLFJSLKJ8633Z17',
name: 'MR NAMLA EMAD',
bic: 'PSSTFRPPCNE',
beneficiaryId: '60a11891-81ba-4ab2-9b92-ce4f461c2d50',
},
];
return (
<Form
{...layout}
name="test"
onFinish={onFinish}
onFinishFailed={onFinishFailed}
autoComplete="off"
>
<Form.Item label="Nom du bénéficiare" name="benef">
<Select
defaultValue=""
style={{ width: 300, marginBottom: 20 }}
onChange={handleChangeBeneficiary}
>
{beneficiaries.map((nom) => (
<Option value={nom.name}> {nom.name} </Option>
))}
</Select>
</Form.Item>
<Form.Item label="IBAN">
<Input autoComplete="off" style={{ marginBottom: 20 }} value={iban}/>
</Form.Item>
<Form.Item wrapperCol={{ ...layout.wrapperCol, offset: 8 }}>
<Button type="primary" htmlType="submit">
Submit
</Button>
</Form.Item>
</Form>
);
};
ReactDOM.render(<Demo />, document.getElementById('container'));
I spend almost 1 week to solve this problem.
I want to disable the button while the field gets an error.
Somehow always the form.getFieldsError() gets Array(0), even the error message this is required or should be 7 digit was showed up.
If you have any idea please help me.
this is my code.
import React from 'react';
import { Form, Input, Button } from 'antd';
import { MinusCircleOutlined, PlusOutlined } from '#ant-design/icons';
const DynamicFieldSet = () => {
const MAX = 3;
const [form] = Form.useForm();
const onValuesChange = (changedValues, allValues) => {
console.log(allValues.lines);
};
console.log(
// this is always true
form.getFieldsError().filter(({ errors }) => errors.length).length === 0
);
return (
<Form
initialValues={{ lines: [''] }}
onValuesChange={onValuesChange}
form={form}
name={'lines'}
>
<Form.List name={'lines'}>
{(fields, { add, remove }, { errors }) => {
return (
<div>
{fields.map((field, index) =>
index < MAX ? (
<Form.Item required={false} key={field.key}>
<Form.Item
{...field}
validateTrigger={['onChange', 'onBlur']}
rules={[
{
required: true,
message: 'this is required',
},
{
min: 7,
max: 7,
message: 'should be 7 digit',
},
]}
noStyle
>
<Input
placeholder=""
style={{ width: '50%' }}
type="number"
/>
</Form.Item>
{index === 0 ? (
<>
<PlusOutlined
onClick={() => {
add();
}}
/>
</>
) : index === MAX - 1 ? (
<MinusCircleOutlined onClick={() => remove(field.name)} />
) : (
<>
<PlusOutlined
onClick={() => {
add();
}}
/>
<MinusCircleOutlined
onClick={() => remove(field.name)}
/>
</>
)}
</Form.Item>
) : null
)}
</div>
);
}}
</Form.List>
<Form.Item>
<Button disabled={false} htmlType="submit">
Send
</Button>
</Form.Item>
</Form>
);
};
export default DynamicFieldSet;
I'm not really sure why but form.getFieldsError() is just not going to work. In order to achieve what you need, you should try using form.validateFields() instead.
The validateFields method, returns a promise that shows all the fields' data or errors on them:
form.validateFields()
.then(values => {
// Do something with values
})
.catch(errors => {
// Do something with errors;
});
Note that this will validate all the fields that you haven't even touched, causing all the provided error messages of all the fields to be shown. So, in case you want to validate just one field or so, all you need to do is to provide an array of field's names like ['myInput'].
From here, just create a new state to be set when errors appear and use it to show/hide-enable/disable your button.
I want to use onChange event on Autocomplete component to get current selected values.
The problem is that it does not working as expected, so when I click to check/uncheck value checkbox is still unchecked but in console i can see that new value was added
uncoment this part to make it works:
value={myTempVal}
onChange={(event, newValue) => {
setMyTempVal(newValue);
console.log(newValue);
}}
online demo:
https://codesandbox.io/embed/hardcore-snowflake-7chnc?fontsize=14&hidenavigation=1&theme=dark
code:
const [myTempVal, setMyTempVal] = React.useState([]);
<Autocomplete
open
multiple
value={myTempVal}
onChange={(event, newValue) => {
setMyTempVal(newValue);
console.log(newValue);
}}
disableCloseOnSelect
disablePortal
renderTags={() => null}
noOptionsText="No labels"
renderOption={(option, { selected }) => {
return (
<>
<Checkbox
icon={icon}
checkedIcon={checkedIcon}
style={{ marginRight: 8 }}
checked={selected}
/>
{option.title}
</>
);
}}
options={option2}
// groupBy={option => option.groupName}
getOptionLabel={option => option.title}
renderInput={params => (
<div>
<div>
<SearchIcon />
</div>
<TextField
variant="outlined"
fullWidth
ref={params.InputProps.ref}
inputProps={params.inputProps}
/>
</div>
)}
/>
You need to get donors receivers and options variables out of the function. Those variables get re-created at each render, this means that their reference changes at each render, and as Autocomplete makes a reference equality check to decide if an option is selected he never finds the options selected.
const donors = [...new Set(data.map(row => row.donor))].map(row => {
return {
groupName: "Donors",
type: "donor",
title: row || "null"
};
});
const receivers = [...new Set(data.map(row => row.receiver))].map(row => {
return {
groupName: "Receivers",
type: "receiver",
title: row || "null"
};
});
const option2 = [...donors, ...receivers];
export const App = props => {
const [myTempVal, setMyTempVal] = React.useState([]);
return (
<Autocomplete
open
multiple
...
You can also add getOptionSelected to overwrite the reference check :
<Autocomplete
open
multiple
disableCloseOnSelect
disablePortal
renderTags={() => null}
noOptionsText="No labels"
getOptionSelected={(option, value) => option.title === value.title}
renderOption={(option, { selected }) => {
return (
<>
<Checkbox
icon={icon}
checkedIcon={checkedIcon}
style={{ marginRight: 8 }}
checked={selected}
/>
{option.title}
</>
);
}}
options={option2}
// groupBy={option => option.groupName}
getOptionLabel={option => option.title}
renderInput={params => (
<div>
<div>
<SearchIcon />
</div>
<TextField
variant="outlined"
fullWidth
ref={params.InputProps.ref}
inputProps={params.inputProps}
/>
</div>
)}
/>
This can help:
Replace
checked={selected}
To
checked={myTempVal.filter(obj=>obj.title===option.title).length!==0}
The complete solution
import React from "react";
import "./styles.css";
import TextField from "#material-ui/core/TextField";
import Autocomplete from "#material-ui/lab/Autocomplete";
import CheckBoxOutlineBlankIcon from "#material-ui/icons/CheckBoxOutlineBlank";
import CheckBoxIcon from "#material-ui/icons/CheckBox";
import Checkbox from "#material-ui/core/Checkbox";
import SearchIcon from "#material-ui/icons/Search";
const icon = <CheckBoxOutlineBlankIcon fontSize="small" />;
const checkedIcon = <CheckBoxIcon fontSize="small" />;
const data = [
{ donor: "Trader Joe's", receiver: "Person-to-Person" },
{ donor: "Trader Joe's", receiver: "Homes with Hope" },
{ donor: "Santa Maria", receiver: "Gillespie Center" },
{ donor: "Santa Maria", receiver: null }
];
export const App = props => {
const donors = [...new Set(data.map(row => row.donor))].map(row => {
return {
groupName: "Donors",
type: "donor",
title: row || "null"
};
});
const receivers = [...new Set(data.map(row => row.receiver))].map(row => {
return {
groupName: "Receivers",
type: "receiver",
title: row || "null"
};
});
const option2 = [...donors, ...receivers];
const [myTempVal, setMyTempVal] = React.useState([]);
return (
<Autocomplete
open
multiple
value={myTempVal}
disableCloseOnSelect
disablePortal
renderTags={() => null}
noOptionsText="No labels"
renderOption={(option, { selected }) => {
return (
<>
<Checkbox
onClick={
()=>{
if(myTempVal.filter(obj=>obj.title===option.title).length!==0){
setMyTempVal([...myTempVal.filter(obj=>obj.title!==option.title)],console.log(myTempVal))
}else{
setMyTempVal([...myTempVal.filter(obj=>obj.title!==option.title),option],console.log(myTempVal))
}
}
}
icon={icon}
checkedIcon={checkedIcon}
style={{ marginRight: 8 }}
checked={myTempVal.filter(obj=>obj.title===option.title).length!==0}
/>
{option.title}
</>
);
}}
options={option2}
// groupBy={option => option.groupName}
getOptionLabel={option => option.title}
renderInput={params => (
<div>
<div>
<SearchIcon />
</div>
<TextField
variant="outlined"
fullWidth
ref={params.InputProps.ref}
inputProps={params.inputProps}
/>
</div>
)}
/>
);
};
export default App;
It is bit late to Answer this question but it might help someone.
In your code you have added onChange event in Autocomplete. When you click on checkbox it will trigger 2 times, one for checkbox and one for Autocomplte. Hence 2nd time trigger makes again checkbox unchecked so u get value in console but still checkbox is empty.
You can remove your checkbox in renderOption and use checked and uncheked icon instaed of checkbox.
renderOption={(option, { selected }) => {
return (
<React.Fragment>
{selected ? <CheckedIcon> : <uncheckedIcon>}
<div>
{option.title}
</div>
</React.Fragment>
</>
);
}}