In this my project, I want the values checked to be displaying in front of the filtered applied but this is not working as expected. Anytime a box is checked, it display all the checked value and anytime a box is uncheck, it goes away automatically. Can someone please help me check what I'm doing wrong. codesandbox
My App.js code
import React from "react";
import "./styles.css";
import { useState, useEffect } from "react";
export default function App() {
const [isselected, setisselected] = useState([]);
const OnChange = (e) => {
console.log(e.target.checked);
const ischecked = e.target.checked;
if (ischecked) {
setisselected([...isselected, e.target.value]);
} else {
const index = isselected.indexOf(e.target.value);
isselected.splice(index, 1);
setisselected(isselected);
}
console.log(isselected);
};
useEffect(() => {
console.log(isselected, "value selected");
}, [isselected]);
return (
<div className="App">
<span>
Filters applied:{" "}
{isselected.map((i) => (
<span>{i}</span>
))}
</span>
<div className="first-search">
<input
type="checkbox"
className="input-1"
value="Lastsevendays"
name="last_seven"
id="1"
onChange={OnChange}
/>
<label htmlFor="">Last 7 days</label>
</div>
<div className="first-search">
<input
type="checkbox"
className="input-1"
name="last24"
value="last_24"
id="2"
onChange={OnChange}
/>
<label htmlFor="">Last 24 hours</label>
</div>
</div>
);
}
You are mutating the isselected state when removing filters. Array.prototype.splice mutates the array in-place.
const OnChange = (e) => {
const ischecked = e.target.checked;
if (ischecked) {
setisselected([...isselected, e.target.value]);
} else {
const index = isselected.indexOf(e.target.value);
isselected.splice(index, 1); // <-- mutation!!
setisselected(isselected); // <-- same array reference
}
};
Use Array.prototype.filter to filter by index the isselected array and return a new array reference.
const OnChange = (e) => {
const ischecked = e.target.checked;
if (ischecked) {
setisselected([...isselected, e.target.value]);
} else {
const index = isselected.indexOf(e.target.value);
setisselected((isselected) => isselected.filter((_, i) => i !== index));
}
};
Since the isselected array is storing primitives, you can filter directly by the filter value as well.
setisselected((isselected) =>
isselected.filter((val) => val !== e.target.value)
);
what you're doing is that you are displaying the state with console.log() and it's the nature of console.log() that it shows the previuos value of the state,and also I did some changes in your Onchange function and it's working now try this and then let me know it's working or not:
const OnChange = (e) => {
console.log(e.target.checked);
const ischecked = e.target.checked;
if (ischecked) {
setisselected([...isselected, e.target.value]);
} else {
let temp = [isselected];
const index = temp.indexOf(e.target.value);
temp.splice(index, 1);
setisselected(temp);
}
console.log(isselected);
};