I have an array by default with all the checkbox status as true.
let initialarray = [{name: 'Approved', isChecked: true},
{name: 'Rejected', isChecked: true},
{name: 'Pending', isChecked: true},
{name: 'Cancelled', isChecked: true}]
All the checkboxes are selected, As I set checked to true
When I try to uncheck the approved status I can able to update the respective Object
checked status to false
.
My OnChange Function looks like Below
const onChange = (e) => {
const updatedStatus = initialarray.map((item) =>
item.name === e.target.name
? { ...item, isChecked: e.target.checked }
: item
);
};
updatedstatus= [{name: 'Approved', isChecked: false},
{name: 'Rejected', isChecked: true},
{name: 'Pending', isChecked: true},
{name: 'Cancelled', isChecked: true}]
When I try to uncheck the Rejected name, I am able to update on the rejected status object but the Approved name status again changing to true
.
updatedstatus= [{name: 'Approved', isChecked: true},
{name: 'Rejected', isChecked: false},
{name: 'Pending', isChecked: true},
{name: 'Cancelled', isChecked: true}]
Latest Updated status only I can able to change. other status it was resetting to true
Expected:
expected= [{name: 'Approved', isChecked: false},
{name: 'Rejected', isChecked: false},
{name: 'Pending', isChecked: true},
{name: 'Cancelled', isChecked: true}]
CodePudding user response:
Store that array as a state since states will persist between component updates.
When setting the state in the onChange
, use a call back that takes prevState
.
const { useState } = React
function App() {
const [checkboxes, setCheckboxes] = useState(
[
{name: 'Approved', isChecked: false},
{name: 'Rejected', isChecked: true},
{name: 'Pending', isChecked: true},
{name: 'Cancelled', isChecked: true}
]
)
const onChange = (e) => {
setCheckboxes(prevState => prevState.map((item) =>
item.name === e.target.name
? { ...item, isChecked: e.target.checked }
: item
))
};
console.log(checkboxes)
return (
<div>
{checkboxes.map((box, i) =>
<input
type="checkbox"
checked={box.isChecked}
onChange={onChange}
name={box.name}
key={i} />
)}
</div>
)
}
ReactDOM.render(<App />, window.root)
<script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
<div id="root"></div>
CodePudding user response:
You also need to replace the initialStatus with the updated status. You are again and again looping on the initialArray and never updating it.
const onChange = (e) => {
const updatedStatus = initialarray.map((item) =>
item.name === e.target.name
? { ...item, isChecked: e.target.checked }
: item
);
initialarray = updatedStatus;
};
CodePudding user response:
The issue is that you are using initialarray
to update the state.
const updatedStatus = initialarray.map(...
Instead of you need to use the prevoState
object in the setState
callback.
const initialarray = [
{ name: "Approved", isChecked: true },
{ name: "Rejected", isChecked: true },
{ name: "Pending", isChecked: true },
{ name: "Cancelled", isChecked: true }
];
function App() {
const [state, setState] = React.useState(initialarray);
const onChange = (name) => {
setState((prevState) =>
prevState.map((item) =>
item.name === name ? { ...item, isChecked: !item.isChecked } : item
)
);
};
return (
<div>
{state.map(({ name, isChecked }) => (
<React.Fragment key={name}>
<input
type="checkbox"
id={name}
checked={isChecked}
onChange={() => onChange(name)}
/>
<label htmlFor={name}> {name}</label>
<br />
</React.Fragment>
))}
</div>
);
}
ReactDOM.render(<App />, document.querySelector('.react'));
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div class='react'></div>