I'm working on project where I have an an accordion with checkboxes. When the checkboxes have a value of true they go to my trueItems
array. I have an array filter
that I need to register the change of value to true when the button with handleSubmit
is clicked. The issue that I'm having is with the final part. I'm struggling to figure out how to get the variables in filter
to change to true. I've tried: x => {setFilter({...filter, x,}), true
but that didn't do anything, and I've tried x => {setFilter({...filter, x: true,}),
but that didn't work either. I would really appreciate any help or advice on how to do this. Thank you!
function handleSubmit () {
for (var items of trueItems){
for (var x in filter){
if(x === items.name) {
x => {
setFilter({
...filter,
x,
})
}}}}}
where filter is:
const [filter, setFilter] = useState({
pescatarian: false,
vegan: false,
vegetarian: false,
...
});
and trueItems is:
[{"name": " pescatarian", "value": true}...]
CodePudding user response:
If I understood your needs correctly, this should work. It takes the previous filter state and iterates over trueValues to actualize the filter state. Your "name" in trueItems should match keys of filter object (I see extra space there)
setFilter((oldFilter) => {
newFilter = {...oldFilter};
trueItems.forEach(trueItem => {
newFilter[trueItem.name] = trueItem.value;
});
return newFilter;
});
CodePudding user response:
When you declare a state variable with useState, it returns a pair — an array with two items.
The first item is the current value, and the second is a function that lets you update it.
Then use Spread syntax (...) and reduce to update the original state.
setFilter((currentFilter) => ({
...currentFilter,
...trueItems.reduce((acc, curr) => {
return acc[curr['name']] = curr['value'], acc;
}, {})
}));
Below is a complete code snippet, you can refer to it.
<!DOCTYPE html>
<html>
<head>
<script crossorigin src='https://unpkg.com/react@18/umd/react.production.min.js'></script>
<script crossorigin src='https://unpkg.com/react-dom@18/umd/react-dom.production.min.js'></script>
<script src='https://unpkg.com/@babel/standalone/babel.min.js'></script>
</head>
<body>
<div id='root'></div>
<script type='text/babel'>
const App = React.createElement(() => {
const [filter, setFilter] = React.useState({
'pescatarian': false,
'vegan': false,
'vegetarian': false
});
const trueItems = [
{ 'name': 'pescatarian','value': true },
{ 'name': 'vegetarian','value': true }
];
const handleSubmit = React.useCallback(() => {
setFilter((currentFilter) => ({
...currentFilter,
...trueItems.reduce((acc, curr) => {
return acc[curr['name']] = curr['value'], acc;
}, {})
}));
}, []);
return (
<React.Fragment>
<p>{JSON.stringify(filter)}</p>
<button onClick={handleSubmit}>handleSubmit</button>
</React.Fragment>
);
});
ReactDOM.render(App, document.getElementById('root'));
</script>
</body>
</html>