I’m writing a simple "select all" checkbox that checks/unchecks all other checkboxes, using react native with typescript and FluentUI checkboxes.
Summarized issue: The state of the "select all" checkbox seems to not update according to the state of the other checkboxes. It seems to be true when it should be false, and false when it should be true. Visually it is correct (appears checked), but functionally it keeps the previous state (true or false).
More context / details:
I’m running into an issue where the state of the checkbox does not seem to update correctly. When I check the "select all" checkbox, it selects all other checkboxes as desired. But if I then uncheck some of the checkboxes and then re-check the "select all" checkbox, instead of re-checking every checkbox, it un-checks all of them. The reverse also happens – if I have the "select all" checkbox unchecked, then check ALL other checkboxes, the "select all" checkbox appears visually selected, but if I click on it, it requires two clicks in order to un-check everything. This tells me that the state is opposite of what it should be – when I check all other checkboxes, it should change the state of the "select all" checkbox to true, but it still registers as false, thus causing me to need to click on it twice. And if I check the "select all" checkbox, then uncheck some other checkboxes, it should change the state of the "select all" checkbox to false, but it remains as true, thus causing all checkboxes to be un-checked when I click the "select all" checkbox again.
I’ve followed every possible example of how to make this work and the logic (in my opinion) seems sound, but yet I have this bug.
Here is how I have everything set up; I have two components, one for CheckboxAll, and one for CheckboxCard (it’s a checkbox that appears inside a Card component). The CheckboxCard renders inside the Card component, and the Card and CheckboxAll components render inside a parent component called Workbooks.
Here is the CheckboxAll component:
export const CheckboxAll: React.FunctionComponent<ICheckboxAllProps> = ( props: ICheckboxAllProps, ) => {
return (
<Checkbox
checked={props.isChecked}
onChange={(_, checked) => props.onChange(checked)}
/>
);
};
And here is the code inside the parent Workbooks component:
export const Workbooks: React.FunctionComponent< IWorkbookProps > = (props: IWorkbookProps) => {
// Some other code
const [workbookIds, setWorkbookIds] = React.useState<string[]>([]);
// This function toggles the individual checkboxes
const handleCheck = (workbookId: string) => {
setWorkbookIds((prev) => {
const newState = prev.includes(workbookId)
? prev.filter(id => id !== workbookId)
: [...prev, workbookId];
return newState;
});
}
// This function toggles the 'select all' checkbox
const handleCheckAll = () => {
setWorkbookIds((_) => {
const newState = workbookIds.length === props.workbooks.length
? []
: props.workbooks.map(workbook => workbook.id);
return newState;
});
}
return (
<View>
<CheckboxAll
isChecked={workbookIds.length === props.workbooks.length}
onChange={handleCheckAll}
/>
{props.workbooks.map((workbook, index) => (
<Card
isChecked={workbookIds.includes(workbook.id)}
onChange={() => handleCheck(workbook.id)}
/>))}
</View>
);
};
All other checkboxes work exactly as expected, it’s only the "select all" checkbox which seems to have its state not updating properly in that specific scenario.
I’ve tried every example I found on Google and I have also tried asking AI. The AI tends to simply re-write my code to do exactly what it is already doing.
Is there a way to better update the state of checkboxes that I have not found?
Thank you very much for your help.
2
Answers
I finally figured out the issue with the select all checkbox: React was still updating the states asynchronously thus the
handleCheckAll
function was not using the most up-to-date state. Even though I was using the functional state of useState, I had to actually use the "prev" variable the same way I did inhandleCheck
. This was the fix:I found it much more intuitive to just add an isChecked prop to
workbookIds
and to manipulate that value. I didnt know which Checkbox component you were using so I just used react-native-paperAnd then the main component:
demo