'Having trouble getting checkboxes to programmatically reset with React Bootstrap
I've found a solution for programmatically resetting the options on my list of checkboxes, however, for some reason, the graphical element itself does not change to match the state. I assumed it would do it automatically on state change, however, it appears there has to be a way that i'm supposed to be doing it sepearately, in addition to what I'm currently doing.
First, I initialize my checkbox options:
const [categoryFilterOptions, setCategoryFilterOptions] = useState([{label: 'Category1', checked: true}, {label: 'Category2', checked: true}, {label: 'Category3', checked: true}, {label: 'Category4', checked: true}])
This is passed into my checklist component on render and processed like this:
{checks.map((checkItem, i) => (
<Form.Check
key={i}
id={i}
type='checkbox'
label={checkItem.label}
defaultChecked={checkItem.checked}
onClick={() => {setCheck(i)}}
></Form.Check>
)) }
Then to reset them, I have a button:
<Button style={{width: '100%'}} onClick={() => {resetAllChecks()}}>Reset Filter</Button>
Which calls the method resetAllChecks() which just sets my check options back to their initial state:
const resetAllChecks = () => {
setFamilyFilterOptions([{label: 'String', checked: true}, {label: 'Percussion', checked: true}, {label: 'Brass', checked: true}, {label: 'Wind', checked: true}, {label: 'Electronic', checked: true}, {label: 'Keyboard', checked: true}])
setCategoryFilterOptions([{label: 'Contemporary', checked: true}, {label: 'Orchestral', checked: true}, {label: 'Traditional', checked: true}, {label: 'Vocal', checked: true}])
}
I'm really not sure why it refuses to reset the graphical element of the checkboxes, because the list get's reset perfectly fine, yet the checkboxes don't.
Edit: Here is some of the surrounding code, which may be better for context?
Programmatically, it works perfect on the data side, it's just the graphics not updating, so i'm not sure if this will be a ton of help, but it's worth a shot!
const DropdownChecklist = ({disabled, checkOptions, returnChecksState}) => {
const [checks, setChecks] = useState([...checkOptions]);
function setCheck(id){
var newArray = [...checks]
var newElement = checks[id];
newElement.checked = (!newElement.checked)
newArray[id] = newElement;
setChecks(newArray);
returnChecksState(checks);
}
console.log(checks)
return (
<Form className={styles.checkMenu}>
<fieldset disabled={disabled}>
{checks.map((checkItem, i) => (
<Form.Check
key={i}
id={i}
type='checkbox'
label={checkItem.label}
checked={checkItem.checked}
onChange={() => {setCheck(i)}}
></Form.Check>
)) }
</fieldset>
</Form>
)
}
export default DropdownChecklist
Edit 2: Even more context
<Col>
<h5 style={{textAlign: 'center', color: 'white'}}>Category Filtering: </h5>
<DropdownChecklist disabled={false} checkOptions={categoryFilterOptions} returnChecksState={setCategoryFilterOptions}></DropdownChecklist>
</Col>
Edit 3: I tried using the solution offered Here, and it's still not working, however, i have now realized that somehow, my component logic which is resetting my checks is somehow directly touching my DEFAULT_CHECKS values which makes no sense to me, especially since it is a const value, that shouldn't even be able to change
Solution 1:[1]
The defaultChecked prop is only meant to be used with uncontrolled components, which under most circumstances you will not need. The behaviour you're seeing is expected:
Changing the value of defaultValue attribute after a component has mounted will not cause any update of the value in the DOM.
You should generally prefer controlled components when you want to programmatically manipulate your input values. The idea is that the input should always get its value from the state in React, and interaction with the input should update the state accordingly.
For a checkbox, that means setting the checked and onChange props, so it could look something like:
{checks.map((checkItem, i) => (
<Form.Check
key={i}
id={i}
type='checkbox'
label={checkItem.label}
checked={checkItem.checked}
onChange={() => {setCheck(i)}}
></Form.Check>
)) }
Now when you call resetAllChecks(), the checkboxes should re-render with the latest values in the state.
Solution 2:[2]
Don't use uncontrolled components sir bad practice.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Serlite |
| Solution 2 | Golden Samurai |
