Reputation: 1832
I am using Material-UI and React Hooks. I am running a loop in which I am printing the checkboxes. I am unable to check or uncheck them. They seem to be readonly. Nothing happens when I click on them. I console logged to see and the hooks are working fine and selectedExpertArr
state is getting updated properly but the checkboxes are not getting checked.
The code is like:
const [selectedExpertArr, setSelectedExpertArr] = useState([]);
The handler function is as follows:
const handleSelectedExperts = (e) => {
console.log('selectedExpertArr')
let clonedExpertArr = [...selectedExpertArr];
if(e.target.checked === true) {
clonedExpertArr.push(e.target.value)
setSelectedExpertArr(clonedExpertArr);
} else {
let filtered = selectedExpertArr.filter((expert) => {
return expert !== e.target.value;
});
clonedExpertArr = filtered;
setSelectedExpertArr(clonedExpertArr);
}
}
The loop code is as follows:
<DialogContent>
<List>
{expertNames.map(expert => (
<ListItem button key={expert.id}>
<Checkbox
checked={(selectedExpertArr.indexOf(expert.id) > -1)? true : false }
name="expertCheckbox"
onChange={handleSelectedExperts}
value={expert.id}
color="primary"
inputProps={{ 'aria-label': 'expert checkbox' }}
/>
<ListItemText primary={expert.username} />
</ListItem>
))}
</List>
</DialogContent>
Upvotes: 1
Views: 1282
Reputation: 16122
It's because clonedExpertArr.push(e.target.value)
saves the value as a string and you are comparing a number here
checked={(selectedExpertArr.indexOf(expert.id) > -1)? true : false }
Upvotes: 1
Reputation: 1776
I guess the issue is with fetching value from target in the hook. Pass that in the loop using arrow function like
<DialogContent>
<List>
{expertNames.map(expert => (
<ListItem button key={expert.id}>
<Checkbox
checked={(selectedExpertArr.indexOf(expert.id) > -1)? true : false }
name="expertCheckbox"
onChange={(e)=> {handleSelectedExperts(e, expert.id)}}
value={expert.id}
color="primary"
inputProps={{ 'aria-label': 'expert checkbox' }}
/>
<ListItemText primary={expert.username} />
</ListItem>
))}
</List>
</DialogContent>
Then modify your hook like pasted below:
const handleSelectedExperts = (e, value) => {
console.log('selectedExpertArr')
let clonedExpertArr = [...selectedExpertArr];
if(e.target.checked) {
clonedExpertArr.push(value)
setSelectedExpertArr(clonedExpertArr);
} else {
let filtered = selectedExpertArr.filter((expert) => {
return expert !== value;
});
clonedExpertArr = filtered;
setSelectedExpertArr(clonedExpertArr);
}
}
Hope that works for you :)
Upvotes: 0
Reputation: 11848
The e.target.value
is of type string, but seems, that expert.id
is number. So you are adding to clonedExpertArr
strings but search for number (selectedExpertArr.indexOf(expert.id) > -1)
To correct, convert e.target.value
to number with +e.target.value
The corrected code will be
const handleSelectedExperts = (e) => {
console.log('selectedExpertArr')
let clonedExpertArr = [...selectedExpertArr];
if(e.target.checked === true) {
clonedExpertArr.push(+e.target.value)
setSelectedExpertArr(clonedExpertArr);
} else {
let filtered = selectedExpertArr.filter((expert) => {
return expert !== +e.target.value;
});
clonedExpertArr = filtered;
setSelectedExpertArr(clonedExpertArr);
}
}
Working demo
Upvotes: 1