onChange react-select multiple options - javascript

I need to detect if I tipe into a searchable react-select. According to the official documentation first of all I have to pass isMulti prop in order to select more than an option.
The actual built-in onChange detects changes only when I select an option, and not when I type into the box. I need it because I have to call an API if I type into that input box.
Here is My select:
<Select
options={myOptions}
isMulti
loadingIndicator={true}
styles={selectStyle}
onChange={(e) => console.log(`e`, e)}
/>
Actually onChange logs me an array with the options selected. How can I change that for example if I type "fo" then I have "fo"? Is there any option or way to do so?

Yes, we have async select option to load data from API when user type.
Below I have attached the code for you documented in their official website.
https://react-select.com/home#async
import { useState } from "react";
import AsyncSelect from "react-select/async";
const colourOptions = [
{ label: "Oranage", value: "orange" },
{ label: "Yellow", value: "yellow" },
{ label: "Blue", value: "blue" }
];
const SelectOption = () => {
const [inputValue, setInputValue] = useState("");
const filterColors = (inputValue) => {
return colourOptions.filter((i) =>
i.label.toLowerCase().includes(inputValue.toLowerCase())
);
};
const promiseOptions = (inputValue, callback) => {
setTimeout(() => {
callback(filterColors(inputValue));
}, 1000);
};
const handleChange = (newValue) => {
const inputValue = newValue.replace(/\W/g, "");
setInputValue(inputValue);
return inputValue;
};
return (
<AsyncSelect
cacheOptions
defaultOptions
loadOptions={promiseOptions}
onInputChange={handleChange}
/>
);
};
export default SelectOption;

There is no onKeyDown props available in react-select's documentation.
What you can do is something like below:
class App extends Component {
onKeyUp = () => {
console.log("I see");
// Your rest code
};
render() {
return (
<div onKeyUp={this.onKeyUp} className="App">
<Select
options={myOptions}
isMulti
loadingIndicator={true}
styles={selectStyle}
onChange={(e) => console.log(`e`, e)}
/>
</div>
);
}
}

Related

MUI Select with Array of Objects as values. How to unselect predefined state?

I have an array of object that looks like this:
[
{
_id: "6311c197ec3dc8c083d6b632",
name: "Safety"
},
........
];
I load this array as potential Menu Items for my Select:
{categoryData &&
categoryData.map((cat: any) => (
<MenuItem key={cat._id} value={cat}>
<Checkbox
checked={categories.some((el: any) => el._id === cat._id)}
/>
<ListItemText primary={cat.name} />
</MenuItem>
))}
In my Select I have predefined value for it:
const [categories, setCategories] = useState([
{
name: "Safety",
_id: "6311c197ec3dc8c083d6b632"
}
]);
.......
<Select
labelId="demo-multiple-checkbox-label"
id="demo-multiple-checkbox"
multiple
value={categories}
onChange={(event: any) => {
const {
target: { value }
} = event;
console.log(value);
setCategories(value);
}}
input={<OutlinedInput label="Tag" />}
renderValue={(selected) => selected.map((cat) => cat.name).join(", ")}
>
The problem is I am unable to unselect(de-select) the predefined value. In stead of removing it from array of categories I got it once again in it.
Here is the sandbox example:
https://codesandbox.io/s/recursing-river-1i5jw8?file=/src/Select.tsx:632-757
I understand that values has to be exactly equal to be removed but how I can do that? What is wrong with this kind of handling?
Also I found this case as reference but still couldn't do it as in the case they use formik:
Unselect MUI Multi select with initial value
You can't directly save the Object as the value. You must use a unique string or stringify the entire object and store it as the value. And based on that value calculate the selected value rendered text. Here is something that will work for you.
Changes: use _id as the value instead of the entire object. And added a new selected value renderer.
import {
FormControl,
Select,
MenuItem,
InputLabel,
Checkbox,
ListItemText,
OutlinedInput
} from "#mui/material";
import React, { useState, useMemo } from "react";
const categoryData = [
{
_id: "6311c197ec3dc8c083d6b632",
name: "Safety"
},
{
_id: "6311c8e6ec3dc8c083d6b63b",
name: "Environment"
},
];
const SelectForm = () => {
const [categories, setCategories] = useState(["6311c197ec3dc8c083d6b632"]);
const selectedCategories = useMemo(() => {
let value = "";
categoryData.forEach((cat) => {
if (categories.some((catId: any) => catId === cat._id)) {
if (value) {
value += ", " + cat.name;
} else {
value = cat.name;
}
}
});
return value;
}, [categories]);
return (
<FormControl fullWidth>
<InputLabel id="demo-multiple-checkbox-label">Category</InputLabel>
<Select
labelId="demo-multiple-checkbox-label"
id="demo-multiple-checkbox"
multiple
value={categories}
onChange={(event: any) => {
const {
target: { value }
} = event;
console.log(value);
setCategories(value);
}}
input={<OutlinedInput label="Tag" />}
renderValue={() => selectedCategories}
>
{categoryData &&
categoryData.map((cat: any) => (
<MenuItem key={cat._id} value={cat._id}>
<Checkbox
checked={categories.some((catId: any) => catId === cat._id)}
/>
<ListItemText primary={cat.name} />
</MenuItem>
))}
</Select>
</FormControl>
);
};
export default SelectForm;
Initially, you have to pass an empty array while setting the state. This will solve your problem.
Code changes will look like this -
const [categories, setCategories] = useState([]);

Programmatically select an option with react-select

I have a basic understanding of React. I'm using react-select and I want to programmatically select an option. For example, with the code below, how to select option B on clicking the button?
This page mentions a setValue function, but I don't understand how to use it. I don't know what is a "ref" in React and how to use it, and I found similar questions on SO with answers assuming this knowledge.
import { useState } from "react";
import Select from "react-select";
const options = [
{ value: "A", label: "A" },
{ value: "B", label: "B" }
];
export default function App() {
const [selectedOption, setSelectedOption] = useState("A");
const handleChange = (value) => {
setSelectedOption(value);
};
return (
<div className="App">
<Select
value={selectedOption}
onChange={handleChange}
options={options}
/>
<button onClick={() => ????????}>Select B</button>
</div>
);
}
You can use the following code.
import { useState } from "react";
import Select from "react-select";
const options = [
{ value: "A", label: "A" },
{ value: "B", label: "B" }
];
export default function App() {
const [selectedOption, setSelectedOption] = useState(options[0]);
const handleChange = (value) => {
setSelectedOption(value);
};
return (
<div className="App">
<Select
value={selectedOption}
onChange={handleChange}
options={options}
/>
<button onClick={() => setSelectedOption(options[1])}>Select B</button>
</div>
);
}
React-Select is different with Select from Material UI. React-Select receives the object of options and set, display the value according to the object.

MaterialUI Compoent does not AutoComplete when data is available

I can't get my component to show my autosuggestions.
It is observed in the console that my data is available and I sent it to this component using the suggestions prop, using Material UI AutoComplete component feature here I am trying to set my options, and these are changing as I type as it's handled in a parent component, but setting the values does not seem to reflect nor bring up my suggestions. I am very confused. my code is below.
import React, { FunctionComponent, FormEvent, ChangeEvent } from "react";
import { Grid, TextField, Typography } from "#material-ui/core";
import { CreateProjectModel, JobModel } from "~/Models/Projects";
import ErrorModel from "~/Models/ErrorModel";
import Autocomplete from "#material-ui/lab/Autocomplete";
type CreateProjectFormProps = {
model: CreateProjectModel;
errors: ErrorModel<CreateProjectModel>;
onChange: (changes: Partial<CreateProjectModel>) => void;
onSubmit?: () => Promise<void>;
suggestions: JobModel[];
};
const CreateProjectForm: FunctionComponent<CreateProjectFormProps> = ({
model,
errors,
onChange,
onSubmit,
suggestions,
}) => {
const [open, setOpen] = React.useState(false);
const [options, setOptions] = React.useState<JobModel[]>([]);
const loading = open && options.length === 0;
const [inputValue, setInputValue] = React.useState('');
React.useEffect(() => {
let active = true;
if (!loading) {
return undefined;
}
(async () => {
if (active) {
setOptions(suggestions);
}
})();
return () => {
active = false;
};
}, [loading]);
React.useEffect(() => {
if (!open) {
setOptions([]);
}
}, [open]);
const submit = async (event: FormEvent) => {
event.preventDefault();
event.stopPropagation();
await onSubmit();
};
const change = (name: string) => (event: ChangeEvent<HTMLInputElement>) => {
setInputValue(event.target.value);
onChange({
[name]: event.target.value,
});
};
const getFieldProps = (id: string, label: string) => {
return {
id,
label,
helperText: errors[id],
error: Boolean(errors[id]),
value: model[id],
onChange: change(id),
};
};
return (
<Autocomplete
{...getFieldProps}
open={open}
onOpen={() => {
setOpen(true);
}}
onClose={() => {
setOpen(false);
}}
getOptionSelected={(option, value) => option.id === value.id}
getOptionLabel={(option) => option.id}
options={options}
loading={loading}
autoComplete
includeInputInList
renderInput={(params) => (
<TextField
{...getFieldProps("jobNumber", "Job number")}
required
fullWidth
autoFocus
margin="normal"
/>
)}
renderOption={(option) => {
return (
<Grid container alignItems="center">
<Grid item xs>
{options.map((part, index) => (
<span key={index}>
{part.id}
</span>
))}
<Typography variant="body2" color="textSecondary">
{option.name}
</Typography>
</Grid>
</Grid>
);
}}
/>
);
};
export default CreateProjectForm;
Example of my data in suggestions look like this:
[{"id":"BR00001","name":"Aircrew - Standby at home base"},{"id":"BR00695","name":"National Waste"},{"id":"BR00777B","name":"Airly Monitor Site 2018"},{"id":"BR00852A","name":"Cracow Mine"},{"id":"BR00972","name":"Toowoomba Updated"},{"id":"BR01023A","name":"TMRGT Mackay Bee Creek"},{"id":"BR01081","name":"Newman Pilot Job (WA)"},{"id":"BR01147","name":"Lake Vermont Monthly 2019"},{"id":"BR01158","name":"Callide Mine Monthly Survey 2019"},{"id":"BR01182","name":"Lake Vermont Quarterly 2019 April"}]
The problem in your code are the useEffects that you use.
In the below useEffect, you are actually setting the options to an empty array initially. That is because you autocomplete is not open and the effect runs on initial mount too. Also since you are setting options in another useEffect the only time your code is supposed to work is when loading state updates and you haven't opened the autocomplete dropdown.
The moment you close it even once, the state is updated back to empty and you won't see suggestions any longer.
React.useEffect(() => {
if (!open) {
setOptions([]);
}
}, [open]);
The solution is simple. You don't need to keep a local state for options but use the values coming in from props which is suggestions
You only need to keep a state for open
const CreateProjectForm: FunctionComponent<CreateProjectFormProps> = ({
model,
errors,
onChange,
onSubmit,
suggestions,
}) => {
const [open, setOpen] = React.useState(false);
const loading = open && suggestions.length === 0;
const [inputValue, setInputValue] = React.useState('');
const submit = async (event: FormEvent) => {
event.preventDefault();
event.stopPropagation();
await onSubmit();
};
const change = (name: string) => (event: ChangeEvent<HTMLInputElement>) => {
setInputValue(event.target.value);
onChange({
[name]: event.target.value,
});
};
const getFieldProps = (id: string, label: string) => {
return {
id,
label,
helperText: errors[id],
error: Boolean(errors[id]),
value: model[id],
onChange: change(id),
};
};
return (
<Autocomplete
{...getFieldProps}
open={open}
onOpen={() => {
setOpen(true);
}}
onClose={() => {
setOpen(false);
}}
getOptionSelected={(option, value) => option.id === value.id}
getOptionLabel={(option) => option.id}
options={suggestions}
loading={loading}
autoComplete
includeInputInList
renderInput={(params) => (
<TextField
{...getFieldProps("jobNumber", "Job number")}
required
fullWidth
autoFocus
margin="normal"
/>
)}
renderOption={(option) => {
return (
<Grid container alignItems="center">
<Grid item xs>
{options.map((part, index) => (
<span key={index}>
{part.id}
</span>
))}
<Typography variant="body2" color="textSecondary">
{option.name}
</Typography>
</Grid>
</Grid>
);
}}
/>
);
};
export default CreateProjectForm;
i noticed a few issues with your code, getFieldProps is being called without the id or name params which cause the page to not load. More importantly, you should consider following the autocomplete docs when passing and using props to it. for example:
renderInput={(params) => <TextField {...params} label="Controllable" variant="outlined" />}
i asked a few questions, pls let me know when you can get those answers so i may address all the issues that may come up.
Q1. should the user input provide relevant matches from the name property in your suggestions or just the id? for ex. if i type "lake", do you want to show BRO1182, Lake Vermont Quarterly 2019 April as a match?
Q2. how did you want to address the error case? i see you have a error model, but unsure how you wish to use it to style the autocomplete when an error occurs
Q3. are we missing a submit button? i see the onSubmit function but it's not used in our code.
Q4. is there a particular reason why you need the open and loading states?
below is what i attempted so far to show related matches from user input
import React, { FunctionComponent, FormEvent, ChangeEvent } from "react";
import { Grid, TextField, Typography } from "#material-ui/core";
import { CreateProjectModel, JobModel } from "~/Models/Projects";
import ErrorModel from "~/Models/ErrorModel";
import Autocomplete from "#material-ui/lab/Autocomplete";
type CreateProjectFormProps = {
model: CreateProjectModel;
errors: ErrorModel<CreateProjectModel>;
onChange: (changes: Partial<CreateProjectModel>) => void;
onSubmit?: () => Promise<void>;
suggestions: JobModel[];
};
const CreateProjectForm: FunctionComponent<CreateProjectFormProps> = ({
model,
errors,
// mock function for testing
// consider a better name like selectChangeHandler
onChange = val => console.log(val),
// consider a better name like submitJobFormHandler
onSubmit,
suggestions: options = [
{ id: "BR00001", name: "Aircrew - Standby at home base" },
{ id: "BR00695", name: "National Waste" },
{ id: "BR00777B", name: "Airly Monitor Site 2018" },
{ id: "BR00852A", name: "Cracow Mine" },
{ id: "BR00972", name: "Toowoomba Updated" },
{ id: "BR01023A", name: "TMRGT Mackay Bee Creek" },
{ id: "BR01081", name: "Newman Pilot Job (WA)" },
{ id: "BR01147", name: "Lake Vermont Monthly 2019" },
{ id: "BR01158", name: "Callide Mine Monthly Survey 2019" },
{ id: "BR01182", name: "Lake Vermont Quarterly 2019 April" }
]
}) => {
const [value, setValue] = React.useState<JobModel>({});
const loading = open && options.length === 0;
// this pc of code is not used, why?
const submit = async (event: FormEvent) => {
event.preventDefault();
event.stopPropagation();
await onSubmit();
};
const handleChange = (_: any, value: JobModel | null) => {
setValue(value);
onChange({
[value.name]: value.id
});
};
// consider passing in props instead
const getFieldProps = (id: string, label: string) => {
return {
id,
label,
// not sure what this is
helperText: errors[id],
// not sure what this is
error: Boolean(errors[id]),
value: model[id],
onChange: change(id)
};
};
return (
<Autocomplete
id="placeholder-autocomplete-input-id"
// for selection, use value see docs for more detail
value={value}
onChange={handleChange}
getOptionSelected={(option, value) => option.id === value.id}
getOptionLabel={option => option.id}
options={options}
loading={loading}
autoComplete
includeInputInList
renderInput={params => (
// spreading the params here will transfer native input attributes from autocomplete
<TextField
{...params}
label="placeholder"
required
fullWidth
autoFocus
margin="normal"
/>
)}
renderOption={option => (
<Grid container alignItems="center">
<Grid item xs>
<span key={option}>{option.id}</span>
<Typography variant="body2" color="textSecondary">
{option.name}
</Typography>
</Grid>
</Grid>
)}
/>
);
};
export default CreateProjectForm;
and you can see the code running in my codesandbox by clicking the button below
If I understand your code and issue right, you want -
React.useEffect(() => {
let active = true;
if (!loading) {
return undefined;
}
(async () => {
if (active) {
setOptions(suggestions);
}
})();
return () => {
active = false;
};
}, [loading]);
to run each time and update options, but the thing is, [loading] dependency setted like
const loading = open && suggestions.length === 0;
and not gonna trigger changes.
Consider doing it like so -
const loading = useLoading({open, suggestions})
const useLoading = ({open, suggestions}) => open && suggestions.length === 0;

update is not capturing and unable to update the input field

please find below code which contains name id and am rendering initially using map
am replacing id value to input type in UI
with the updated input type am trying to update the value onchange
update is not capturing and unable to update the input field
any suggestion?
please refer below snippet
import React, { useState } from "react";
const CstmInput = (props) => {
return (
<input
name={props.name}
type="text"
value={props.value}
onChange={(event) => props.onInputChange(event)}
/>
);
};
export default CstmInput;
import React, { useState } from "react";
import CstmInput from "./CstmInput";
const HierarcyTest = () => {
let rowData = [
{ name: "first", id: 10 },
{ name: "second", id: 20 },
];
const [data, setData] = useState(rowData);
const [name, setName] = useState({ fn: "test" });
const onInputChange = (e) => {
console.log("---event---", e.target.value);
setName({ ...name, fn: e.target.value });
};
let updateValue = () => {
let newData = data.map(
(item, index) =>
(item.id = (
<CstmInput name={item.name} value={item.id} onInputChange={(e) => onInputChange(e)} />
))
);
setData([...data, newData]);
};
return (
<div>
<div>Testing</div>
{data.map((val) => (
<h6>
{" "}
{val.name} {val.id}
</h6>
))}
<button onClick={updateValue}> Click </button>
</div>
);
};
export default HierarcyTest;
A few things why your code isn't working as intended:
1.
let updateValue = () => {
let newData = data.map((item, index) => {
if (item.id === 10) {
return [
(item.id = (
<CstmInput
value={item.id}
onInputChange={(e) => onInputChange(e)}
/>
)),
];
}
});
setData([...data, newData]);
};
In the above function inside the callback of map, you're only returning when a condition satisfies. Are you trying to filter the array instead? If not then return something when the if condition fails.
And why are you returning an array?
return [
(item.id = (
<CstmInput
value={item.id}
onInputChange={(e) => onInputChange(e)}
/>
)),
];
the above code seems logically wrong.
2.
const onInputChange = (e) => {
console.log("---event---", e.target.value);
setName({ ...name, fn: e.target.value });
};
If you want to update state which depends on the previous state then this is how you do it:
setName((prevState) => ({ ...prevState, fn: e.target.value }));
but since you're not actually relying on the properties of the previous state you can just use:
setName({fn: e.target.value });
Note that since your state only has one property and you want to update that single property you can completely overwrite the state, you don't need to spread the previous state.
update
change the updateValue function as the following:
let updateValue = () => {
setData(prevData => {
return prevData.map(el => {
return { ...el, id: <CstmInput value={el.id} onInputChange={(e) => onInputChange(e)} /> };
})
});
};
A stackblitz example I've created that implements what you're trying to do.

How to implement multiple checkbox using react hook

I want to implement multiple checkboxes on my HTML page using react-hook.
I tried implementing using this URL: https://medium.com/#Zh0uzi/my-concerns-with-react-hooks-6afda0acc672. In the provided link it is done using class component and working perfectly but whenever I am using React hook setCheckedItems to update checkbox checked status it's not re-rendering the view.
The very first time the view is rendering and console.log() is printing from Checkbox component. After clicking on checkbox function handleChange gets called and checkedItems updates the value but the view is not rendering again (no console.log() printing). And {checkedItems.get("check-box-1")} is also not printing any value.
Below is my sample code.
CheckboxExample :
import React, { useState } from 'react';
import Checkbox from '../helper/Checkbox';
const CheckboxExample = () => {
const [checkedItems, setCheckedItems] = useState(new Map());
const handleChange = (event) => {
setCheckedItems(checkedItems => checkedItems.set(event.target.name, event.target.checked));
console.log("checkedItems: ", checkedItems);
}
const checkboxes = [
{
name: 'check-box-1',
key: 'checkBox1',
label: 'Check Box 1',
},
{
name: 'check-box-2',
key: 'checkBox2',
label: 'Check Box 2',
}
];
return (
<div>
<lable>Checked item name : {checkedItems.get("check-box-1")} </lable> <br/>
{
checkboxes.map(item => (
<label key={item.key}>
{item.name}
<Checkbox name={item.name} checked={checkedItems.get(item.name)} onChange={handleChange} />
</label>
))
}
</div>
);
}
export default Example;
Checkbox:
import React from 'react';
const Checkbox = ({ type = 'checkbox', name, checked = false, onChange }) => {
console.log("Checkbox: ", name, checked);
return (<input type={type} name={name} checked={checked} onChange={onChange} /> )
}
export default Checkbox;
I don't think using a Map to represent the state is the best idea.
I have implemented your example using a plain Object and it works:
https://codesandbox.io/s/react-hooks-usestate-xzvq5
const CheckboxExample = () => {
const [checkedItems, setCheckedItems] = useState({}); //plain object as state
const handleChange = (event) => {
// updating an object instead of a Map
setCheckedItems({...checkedItems, [event.target.name] : event.target.checked });
}
useEffect(() => {
console.log("checkedItems: ", checkedItems);
}, [checkedItems]);
const checkboxes = [
{
name: 'check-box-1',
key: 'checkBox1',
label: 'Check Box 1',
},
{
name: 'check-box-2',
key: 'checkBox2',
label: 'Check Box 2',
}
];
return (
<div>
<lable>Checked item name : {checkedItems["check-box-1"]} </lable> <br/>
{
checkboxes.map(item => (
<label key={item.key}>
{item.name}
<Checkbox name={item.name} checked={checkedItems[item.name]} onChange={handleChange} />
</label>
))
}
</div>
);
}
EDIT:
Turns out a Map can work as the state value, but to trigger a re-render you need to replace the Map with a new one instead of simply mutating it, which is not picked by React, i.e.:
const handleChange = (event) => {
// mutate the current Map
checkedItems.set(event.target.name, event.target.checked)
// update the state by creating a new Map
setCheckedItems(new Map(checkedItems) );
console.log("checkedItems: ", checkedItems);
}
but in this case, I think there is no benefit to using a Map other than maybe cleaner syntax with .get() and .set() instead of x[y].
As an alternative to Map, you might consider using a Set. Then you don't have to worry about initially setting every item to false to mean unchecked. A quick POC:
const [selectedItems, setSelectedItems] = useState(new Set())
function handleCheckboxChange(itemKey: string) {
// first, make a copy of the original set rather than mutating the original
const newSelectedItems = new Set(selectedItems)
if (!newSelectedItems.has(itemKey)) {
newSelectedItems.add(itemKey)
} else {
newSelectedItems.delete(itemKey)
}
setSelectedItems(newSelectedItems)
}
...
<input
type="checkbox"
checked={selectedItems.has(item.key)}
onChange={() => handleCheckboxChange(item.key)}
/>
Seems a bit of a long way round but if you spread the map out and apply it to a new Map your component will re-render. I think using a Object reference instead of a Map would work best here.
const {useState} = React
const Mapper = () => {
const [map, setMap] = useState(new Map());
const addToMap = () => {
const RNDM = Math.random().toFixed(5)
map.set(`foo${RNDM}`, `bar${RNDM}`);
setMap(new Map([...map]));
}
return (
<div>
<ul>
{[...map].map(([v, k]) => (
<li key={k}>
{k} : {v}
</li>
))}
</ul>
<button onClick={addToMap}>add to map</button>
</div>
);
};
const rootElement = document.getElementById("react");
ReactDOM.render(<Mapper />, rootElement);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="react"></div>
As a supplement to using a single object to hold the state of numerous items, the updates will not occur as expected if updating multiple items within a single render. Newer commits within the render cycle will simply overwrite previous commits.
The solution to this is to batch up all the changes in a single object and commit them all at once, like so:
// An object that will hold multiple states
const [myStates, setMyStates] = useState({});
// An object that will batch all the desired updates
const statesUpdates = {};
// Set all the updates...
statesUpdates[state1] = true;
statesUpdates[state2] = false;
// etc...
// Create a new state object and commit it
setMyStates(Object.assign({}, myStates, statesUpdates));
export default function Input(props) {
const {
name,
isChecked,
onChange,
index,
} = props;
return (
<>
<input
className="popup-cookie__input"
id={name}
type="checkbox"
name={name}
checked={isChecked}
onChange={onChange}
data-action={index}
/>
<label htmlFor={name} className="popup-cookie__label">{name}</label>
</>
);
}
const checkboxesList = [
{name: 'essential', isChecked: true},
{name: 'statistics', isChecked: false},
{name: 'advertising', isChecked: false},
];
export default function CheckboxesList() {
const [checkedItems, setCheckedItems] = useState(checkboxesList);
const handleChange = (event) => {
const newCheckboxes = [...checkedItems];
newCheckboxes[event.target.dataset.action].isChecked = event.target.checked;
setCheckedItems(newCheckboxes);
console.log('checkedItems: ', checkedItems);
};
return (
<ul className="popup-cookie-checkbox-list">
{checkboxesList.map((checkbox, index) => (
<li className="popup-cookie-checkbox-list__item" key={checkbox.name}>
<Input
id={checkbox.name}
name={checkbox.name}
isChecked={checkbox.isChecked}
onChange={handleChange}
index={index}
/>
</li>
))}
</ul>
);
}```

Categories

Resources