I am fetching data from Api and based on api data I am filtering data when I click checkbox and the required data could be retrived i.e filtered data from one checkbox if I click and if I click another checkbox all of data disappears .I want to get all the filtered data which I clicked .Below is my code
import React, { useEffect, useState } from 'react'
const Filter = () => {
const [posts, setPosts] = useState([])
useEffect(() => {
filterData()
}, [])
const filterData = async () => {
const res = await fetch("https://jsonplaceholder.typicode.com/posts")
const data = await res.json()
setPosts(data)
console.log("posts", posts)
}
const handleClick = (e, userId) => {
const { value, checked } = e.target
console.log(userId, "userId")
console.log(value, "val")
if (checked) {
const filterData = posts.filter((item) => item.userId === userId)
setPosts(filterData)
}
else {
filterData()
// const filterDat = posts.filter((e) => e === value)
// setPosts(filterDat)
}
}
return (
<div>
<h2>Filter data</h2>
<label>Userid1</label>
<input type="checkbox" value='a' name='filter' onClick={(e) => handleClick(e, 1)} />
<label>Userid2</label>
<input type="checkbox" value='b' name='filter' onChange={(e) => handleClick(e, 2)} />
<label>Userid3</label>
<input type="checkbox" value='c' name='filter' onChange={(e) => handleClick(e, 3)} />
<label>Userid4</label>
<input type="checkbox" value='d' name='filter' onChange={(e) => handleClick(e, 4)} />
<label>Userid5</label>
<input type="checkbox" value='e' name='filter' onChange={(e) => handleClick(e, 5)} />
<label>Userid6</label>
<input type="checkbox" value='f' name='filter' onChange={(e) => handleClick(e, 6)} />
<label>Userid7</label>
<input type="checkbox" value='g' name='filter' onChange={(e) => handleClick(e, 7)} />
<label>Userid8</label>
<input type="checkbox" value='h' name='filter' onChange={(e) => handleClick(e, 8)} />
<label>Userid9</label>
<input type="checkbox" value='i' name='filter' onChange={(e) => handleClick(e, 9)} />
<label>Userid10</label>
<input type="checkbox" value='j' name='filter' onChange={(e) => handleClick(e, 10)} />
{posts.map((item) => (
<div key={item.id}>
<div>{item.userId} ---- {item.title}</div>
<hr />
<div>{item.body}</div>
</div>
))}
<hr />
</div>
)
}
export default Filter
I want get filtered data based on all checkboxes
CodePudding user response:
You are doing things other way around
- Store somewhere state of the checkboxes e.g.:
const [selected, setSelected] = useState(() => Array(10).fill(false));
// ...
const handleClick = (e, userId) => {
const { value, checked } = e.target;
setSelected((array) =>
array.map((e, i) => (i === userId - 1 ? checked : e))
);
};
- Get filtered posts
const filteredPosts = posts.filter((item) => selected[item.userId - 1]);
import React, { useEffect, useState } from "react";
const Filter = () => {
const [posts, setPosts] = useState([]);
const [selected, setSelected] = useState(() => Array(10).fill(false));
useEffect(() => {
const getData = async () => {
const res = await fetch("https://jsonplaceholder.typicode.com/posts");
const data = await res.json();
setPosts(data);
};
getData();
}, []);
const handleClick = (e, userId) => {
const { value, checked } = e.target;
setSelected((array) =>
array.map((e, i) => (i === userId - 1 ? checked : e))
);
};
const filteredPosts = posts.filter((item) => selected[item.userId - 1]);
return (
<div>
<h2>Filter data</h2>
<label>Userid1</label>
<input
type="checkbox"
value="a"
name="filter"
onClick={(e) => handleClick(e, 1)}
/>
<label>Userid2</label>
<input
type="checkbox"
value="b"
name="filter"
onChange={(e) => handleClick(e, 2)}
/>
<label>Userid3</label>
<input
type="checkbox"
value="c"
name="filter"
onChange={(e) => handleClick(e, 3)}
/>
<label>Userid4</label>
<input
type="checkbox"
value="d"
name="filter"
onChange={(e) => handleClick(e, 4)}
/>
<label>Userid5</label>
<input
type="checkbox"
value="e"
name="filter"
onChange={(e) => handleClick(e, 5)}
/>
<label>Userid6</label>
<input
type="checkbox"
value="f"
name="filter"
onChange={(e) => handleClick(e, 6)}
/>
<label>Userid7</label>
<input
type="checkbox"
value="g"
name="filter"
onChange={(e) => handleClick(e, 7)}
/>
<label>Userid8</label>
<input
type="checkbox"
value="h"
name="filter"
onChange={(e) => handleClick(e, 8)}
/>
<label>Userid9</label>
<input
type="checkbox"
value="i"
name="filter"
onChange={(e) => handleClick(e, 9)}
/>
<label>Userid10</label>
<input
type="checkbox"
value="j"
name="filter"
onChange={(e) => handleClick(e, 10)}
/>
{filteredPosts.map((item) => (
<div key={item.id}>
<div>
{item.userId} ---- {item.title}
</div>
<hr />
<div>{item.body}</div>
</div>
))}
<hr />
</div>
);
};
export default Filter;
CodePudding user response:
Maintain a separate collection for the filered data and filter criterias. Please refer the below code.
Code Sandbox: https://codesandbox.io/s/funny-mestorf-6bunot?file=/src/App.js:0-1647
import React, { useEffect, useState } from "react";
const App = () => {
const userIds = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const [posts, setPosts] = useState([]);
const [filteredData, setFilteredData] = useState([]);
const [selectedFilters, setSelectedFilers] = useState([]);
const filterData = async () => {
const res = await fetch("https://jsonplaceholder.typicode.com/posts");
const data = await res.json();
setPosts(data);
setFilteredData(data);
};
useEffect(() => {
if (selectedFilters.length > 0) {
const filterData = posts.filter((item) => {
return selectedFilters.includes(item.userId);
});
setFilteredData(filterData);
} else {
filterData();
}
}, [selectedFilters]);
const handleClick = (e, userId) => {
const { checked } = e.target;
if (checked) {
setSelectedFilers((prev) => [...prev, userId]);
} else {
setSelectedFilers(selectedFilters.filter((x) => x !== userId));
}
};
return (
<div>
<h2>Filter data</h2>
{userIds.map((id, key) => {
return (
<>
<label>{`UserId:${id}`} </label>
<input
key={key}
type="checkbox"
value="a"
name="filter"
onClick={(e) => handleClick(e, id)}
/>
</>
);
})}
{filteredData.map((item) => (
<div key={item.id}>
<div>
{item.userId} ---- {item.title}
</div>
<hr />
<div>{item.body}</div>
</div>
))}
<hr />
</div>
);
};
export default App;