I am trying to filter array as per gender (using checkbox ) but its not working. When i clicked on male checkbox it works but it wont work by clicking on female checkbox button. Here is my App.tsx. Need help to solve this?
import React, { useState } from "react";
const App = () => {
const [students, setStudents] = useState([
{ id: 1, title: "Akita from place1", race: "Akita", gender: 'female' },
{ id: 2, title: "Akita from place2", race: "Akita", gender: 'female' },
{ id: 3, title: "Akita from place3", race: "Akita", gender: 'female' },
{ id: 4, title: "Chihuahua from place4", race: "Chihuahua" , gender: 'male' },
{ id: 5, title: "Cockapoo from place5", race: "Cockapoo" , gender: 'male'},
{ id: 6, title: "Dachshund from place6", race: "Dachshund", gender: 'male' },
{ id: 7, title: "Dutch Shepherd from place7", race: "Dutch Shepherd" , gender: 'female' },
{ id: 8, title: "Bulldog from place8", race: "Bulldog", gender: 'male' },
{ id: 9, title: "Goldador from place9", race: "Goldador", gender: 'female' },
]);
const filterData = (e: any) => {
console.log(e.target.value);
if (e.target.value === "male") {
const filteredData = students.filter((student) => {
return student.gender === "male";
});
setStudents(filteredData);
}
if (e.target.value === "female") {
const filteredData = students.filter((student) => {
return student.gender === "female";
});
setStudents(filteredData);
}
};
return (
<div>
<h3>app</h3>
Male: <input type="checkbox" name='male' value='male' onChange={filterData} />
Female: <input type="checkbox" name='female' value='female' onChange={filterData} />
{students
.map((student: any) => {
return (
<div key={student.id}>
{student.id}-{student.title}-{student.race}-{student.gender}
</div>
);
})}
</div>
);
};
export default App;
CodePudding user response:
It does not work because you are filtering all the female out and updating the state, this means that after clicking one button once, the filtered values does not exist in state anymore. To fix this, you could track the filter type in state and derive the filtered students during render. Note that you could use radio buttons so only one gender can be selected at a time.
import React, {useState} from "react";
const App = () => {
const [students, setStudents] = useState([
{id: 1, title: "Akita from place1", race: "Akita", gender: 'female'},
{id: 2, title: "Akita from place2", race: "Akita", gender: 'female'},
{id: 3, title: "Akita from place3", race: "Akita", gender: 'female'},
{id: 4, title: "Chihuahua from place4", race: "Chihuahua", gender: 'male'},
{id: 5, title: "Cockapoo from place5", race: "Cockapoo", gender: 'male'},
{id: 6, title: "Dachshund from place6", race: "Dachshund", gender: 'male'},
{id: 7, title: "Dutch Shepherd from place7", race: "Dutch Shepherd", gender: 'female'},
{id: 8, title: "Bulldog from place8", race: "Bulldog", gender: 'male'},
{id: 9, title: "Goldador from place9", race: "Goldador", gender: 'female'},
]);
const [filter, setFilter] = useState<null | string>(null)
const filterData = (e) => {
setFilter(e.target.checked ? e.target.value : null)
};
const filteredStudent = filter ? students.filter(s => s.gender === filter) : students;
return (
<div>
<h3>app</h3>
Male: <input type="checkbox" name='male' value='male' onChange={filterData}/>
Female: <input type="checkbox" name='female' value='female' onChange={filterData}/>
{filteredStudent
.map((student) => {
return (
<div key={student.id}>
{student.id}-{student.title}-{student.race}-{student.gender}
</div>
);
})}
</div>
);
};
export default App;
CodePudding user response:
const {
useState
} = React;
const App = () => {
const [students, setStudents] = React.useState([{
id: 1,
title: "Akita from place1",
race: "Akita",
gender: 'female'
},
{
id: 2,
title: "Akita from place2",
race: "Akita",
gender: 'female'
},
{
id: 3,
title: "Akita from place3",
race: "Akita",
gender: 'female'
},
{
id: 4,
title: "Chihuahua from place4",
race: "Chihuahua",
gender: 'male'
},
{
id: 5,
title: "Cockapoo from place5",
race: "Cockapoo",
gender: 'male'
},
{
id: 6,
title: "Dachshund from place6",
race: "Dachshund",
gender: 'male'
},
{
id: 7,
title: "Dutch Shepherd from place7",
race: "Dutch Shepherd",
gender: 'female'
},
{
id: 8,
title: "Bulldog from place8",
race: "Bulldog",
gender: 'male'
},
{
id: 9,
title: "Goldador from place9",
race: "Goldador",
gender: 'female'
},
]);
const [filtered, setFiltered] = useState([])
const filterData = (e) => {
const {value, checked} = e.target;
//check if value not in state and checked is true then add value to state
if(!filtered.includes(value) && checked){
setFiltered([...filtered, value])
}else{
setFiltered(filtered.filter(f=>f!==value))
}
};
const filteredStudent = filtered.length > 0 ? students.filter(s => filtered.includes(s.gender)) : students;
return (
<div>
<h3>app</h3>
Male: <input type="checkbox" name='male' value='male' onChange={filterData}/>
Female: <input type="checkbox" name='female' value='female' onChange={filterData}/>
{filteredStudent
.map((student) => {
return (
<div key={student.id}>
{student.id}-{student.title}-{student.race}-{student.gender}
</div>
);
})}
</div>
);
};
// Render it
ReactDOM.createRoot(
document.getElementById("root")
).render( <
App / >
);
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>