How to change checkbox value not only by clicking on that checkbox input but on the whole button that wraps input and span?
const statuses = ["Draft", "Pending", "Paid"];
const [checkedState, setCheckedState] = useState(
new Array(statuses.length).fill(false)
);
const handleCheckboxChange = (position: number) => {
const updatedCheckedState = checkedState.map((item, index) =>
index === position ? !item : item
);
setCheckedState(updatedCheckedState);
};
{statuses.map((status, index) => (
<button key={index}>
<input
type="checkbox"
onChange={() => handleCheckboxChange(index)}
/>
<span>{status}</span>
</button>
))}
CodePudding user response:
Move your handleCheckboxChange
function to the button
and use checked
property to input
for handling check-uncheck dynamically. As you see, in the checked
property I give the value dynamically like this checked={checkedState[index]}
.
import { useEffect, useState } from "react";
import "./styles.css";
export default function App() {
const statuses = ["Draft", "Pending", "Paid"];
const [checkedState, setCheckedState] = useState(
new Array(statuses.length).fill(false)
);
const handleCheckboxChange = (position) => {
const updatedCheckedState = checkedState.map((item, index) =>
index === position ? !item : item
);
setCheckedState(updatedCheckedState);
};
return (
<>
{statuses.map((status, index) => (
<button key={index} onClick={() => handleCheckboxChange(index)}>
<input type="checkbox" checked={checkedState[index]} />
<span>{status}</span>
</button>
))}
</>
);
}
And another way is - just use label
instead of button
. In this case you need to give proper styles to the label.
return (
<>
{statuses.map((status, index) => (
<label key={index}>
<input
type="checkbox"
onChange={() => handleCheckboxChange(index)}
checked={checkedState[index]}
/>
<span>{status}</span>
</label>
))}
</>
);
CodePudding user response:
You can just put the handler on the button instead of the input checkbox.
The reason is event in javascript will go from outer tag to inner tag. If you click on a button the event will fired in button before fired in button's children.
For details, see event bubbling and capturing
<button key={index} onClick={() => handleCheckboxChange(index)}>
<input
type="checkbox"
//onChange={() => handleCheckboxChange(index)}
checked={checkedState[index]}
/>
<span>{status}</span>
</button>