How to handle multiple checkboxes using React Hook
Well, the problem is solved. It's all about input attributes. I was passing htmlFor
property into ListItem for item.name
, but not for id. So I needed to create an id property in my checkboxes
array and pass htmlFor
property like this htmlFor={item.id}
Don't forget to pass id
property to ListItem as well like id={item.id}
ReactJS: Manage multiple checkbox inputs with useState
The basic problem is checked={allChecked ? true : isChecked[test.name]}
stops the unchecking action from happening - once allChecked
is true it does not matter what value isChecked[test.name]
has, the expression is always going to be true.
You should rely only on isChecked
for the value, and treat changing allChecked
as a side-effect.
useEffect(() => {
setIsChecked(current => {
const nextIsChecked = {}
Object.keys(current).forEach(key => {
nextIsChecked[key] = allChecked;
})
return nextIsChecked;
});
}, [allChecked]);
...
{formData.map((test, index) => (
<div key={index}>
<label>{test.name}</label>
<input
type="checkbox"
name={test.name}
checked={isChecked[test.name]}
onChange={handleSingleCheck}
/>
</div>
))}
There's also this warning cropping up
Warning: A component is changing an uncontrolled input of type checkbox to be controlled. Input elements should not switch from uncontrolled to controlled (or vice versa). Decide between using a controlled or uncontrolled input element for the lifetime of the component.
So that's basically saying don't initialize isChecked
to {}
, because the input's checked property is initially undefined. Use this instead,
{
test1: false,
test2: false,
test3: false,
test4: false,
test5: false,
}
or this way
const data = { ... }
const initialIsChecked = data.reduce((acc,d) => {
acc[d.name] = false;
return acc;
}, {})
export default function App() {
const [allChecked, setAllChecked] = useState(false);
const [isChecked, setIsChecked] = useState(initialIsChecked);
...
How to work with multiple checkboxes in react and collect the checked checkboxes
Your CheckBox
-component does not contain a key
property. This is helpful for React to identify which items have changed, are added, or are removed.
Source: https://reactjs.org/docs/lists-and-keys.html
I also do not understand why you have two states, checkboxState
and checkedCheckboxes
. Is there another reason for this? I think this would be easier with a single state which holds the indexes (or values) of the checked checkboxes.
[update after comments]
The code below is the desired solution by OP to have the selected object values in a React state.
const { useState } = React;
const Checkboxes = () => {
// With this useState I wan't to collect the checked checkboxes
const [checkedCheckboxes, setCheckedCheckboxes] = useState([]);
// This is my handler method that gets triggered when a checkbox get's checked/unchecked
// ..and toggles the state of the checkbox
const handleCheckboxChange = (data) => {
const isChecked = checkedCheckboxes.some(checkedCheckbox => checkedCheckbox.value === data.value)
if (isChecked) {
setCheckedCheckboxes(
checkedCheckboxes.filter(
(checkedCheckbox) => checkedCheckbox.value !== data.value
)
);
} else {
setCheckedCheckboxes(checkedCheckboxes.concat(data));
}
};
const receivedData = [{ value: "A" }, { value: "B" }, { value: "C" }];
return (
<>
<div className="checkboxes">
<h1>Checkboxes:</h1>
{receivedData?.map((data, index) => (
<input
key={`cb-${index}`}
value={data.value}
type="checkbox"
checked={checkedCheckboxes.some(checkedCheckbox => checkedCheckbox.value === data.value)}
onChange={() => handleCheckboxChange(data)}
/>
))}
</div>
<div>
<h1>State:</h1>
<pre>{JSON.stringify(checkedCheckboxes, null, 2)}</pre>
</div>
</>
);
};
ReactDOM.render(<Checkboxes />, document.getElementById("app"));
react hook how to handle mutiple checkbox
On every re-render you are basically setting isChecked
property to false
. Try updating your component like this:
const CurrentLists = ({ shoppingList }) => {
const [checkedItems, setCheckeditems] = useState(shoppingList)
const handleOnChange = useCallback(
(e) => {
const index = e.target.name
let items = [...checkedItems];
items[index].isChecked = e.target.checked;
setCheckeditems(items);
}, [checkedItems]
);
return (
<div>
{checkedItems.map((item, index) => {
console.log('item check', item.isChecked)
return (
<CheckBox
key={index}
name={index}
checked={item.isChecked}
text={item.name}
onChange={handleOnChange}
/>
)
})}
</div>
)
}
You may also notice usage of useCallback
. It ensures that your callback is memoized and not created on every re-render - more about it.
Handling dynamic checkbox in react-native using hooks
Try this way
const CheckTest = () => {
const [data, setData] = useState([
{
name: 'first'
},
{
name: 'second'
},
{
name: 'third'
},
{
name: 'fourth'
}]);
const onValueChange = (item, index) => {
const newData = [...data];
newData[index].isCheck = !item.isCheck;
setData(newData);
}
return (
<View style={{ paddingTop: 20 }}>
{data.map((item, index) => {
return <CheckBox
title={item.name}
checked={item.isCheck || false}
onPress={(val) => onValueChange(item, index)}
key={item.name}
/>
})}
</View>
)
}
React Select All for multiple checkboxes
You can just have an array at the top to define checkboxes and create the initial state. Then loop into the array to display the checkboxes. Try below code
const dataArray = ['nr1', 'nr2'];
const initialState = dataArray.reduce((o, key) => ({ ...o, [key]: false}), {})
export default function App() {
const [checkedAll, setCheckedAll] = useState(false);
const [checked, setChecked] = useState(initialState);
...
...
return (
<div className="App">
<div>
<label>All</label>
<input
type="checkbox"
onChange={(event) => selectAll(event.target.checked)}
checked={checkedAll}
/>
</div>
{dataArray.map(data => (
<div>
<label>{data}</label>
<input
type="checkbox"
name={data}
onChange={() => toggleCheck(data)}
checked={checked[data]}
/>
</div>
))}
</div>
);
Related Topics
How to Fire an Event When V-Model Changes
Check If a Key Exists Inside a Json Object
Pass Variable from Android to JavaScript Launched in Webview
Can We Insert JavaScript into Any Webpage Loaded in the Browser
Remove Parameter from Url Via Regex
Display a Loading Icon While Images Loads
How to Hide and Show Div by Id Based on the Value of Selected Drop Down -Jquery and JavaScript
Google Charts - Labels Are Not Showing
Ask for Geolocation Permission Again If It Was Denied
Why Am I Getting an Expected an Assignment or Function Call and Instead Saw an Expression
How to Get Route Url Params in a Page in Nuxt2 and 3
How to Toggle Class to a Div Element in Reactjs
Reactjs Dynamic Drop Down Populated With Map Function
Image Upload With Preview and Delete Option - Javascript/Jquery
How to Get a File() or Blob() from an Url in JavaScript
Cors - Response to Preflight Request Doesn't Pass Access Control Check