React如何使用多个复选框过滤数据数组 [英] React How to Filter Data Array using Multiple Checkbox
问题描述
我打算通过以下代码选择不同的复选框来过滤数据:
const movieData = [{标题:电影0",风格:"},{标题:电影1",类型:[动作",惊悚片"]},{标题:电影2",类型:[喜剧",戏剧"]},{标题:电影3",类型:[喜剧",动作"]},{标题:电影4",体裁:惊悚"},{标题:电影5",风格:喜剧"},{标题:电影6",风格:动作"},{标题:电影7",风格:戏剧"}];
const movie = [{体裁:惊悚"},{体裁:喜剧"},{风格:动作";},{风格:戏剧"}];const FilterMethod01 =()=>{const [genre,setGenre] = useState(["]]);const [filteredGenre,setFilteredGenre] = useState(["]]);const handleChange = e =>{如果(e.target.checked){setGenre([... genre,e.target.value]);} 别的 {setGenre(genre.filter(id => id!== e.target.value));}};useEffect(()=> {setFilteredGenre(movieData.filter(movie =>genre.some(类别=>类别=== movie.genre)));}, [类型]);返回 (<片段>< FormControl>< FormGroup>{movie.map(movie =>(< FormControlLabelcontrol = {<复选框onChange = {handleChange}/>}标签= {movie.genre}值= {movie.genre}/>))}</FormGroup></FormControl>{filteredGenre.map((movie,index)=>(<卡片样式= {{背景:浅绿色",边距底部:"5px"}}><版式装订线GutterBottom变体="h6".noWrap>标题:{movie.title}</Typography><版式装订线GutterBottom变体="h6".noWrap>体裁:{movie.genre}</Typography></卡>))}</片段>);};
但是,此代码存在以下问题:
-
所有映射数据
[电影0",电影1",电影2",电影3" ...]
均未出现默认.如何使所有映射的数据默认显示? -
映射的数据仅过滤单个字符串(例如
{genre:""}
),而不是字符串数组(例如{genre:["thriller";,"action"]]
).如何选择操作"复选框以触发电影1",电影3"和"电影6"出现?
#在I intend to filter data by selecting different checkbox through the following codes:
const movieData = [ { title: "movie 0", genre: "" }, { title: "movie 1", genre: ["action", "thriller"] }, { title: "movie 2", genre: ["comedy", "drama"] }, { title: "movie 3", genre: ["comedy", "action"] }, { title: "movie 4", genre: "thriller" }, { title: "movie 5", genre: "comedy" }, { title: "movie 6", genre: "action" }, { title: "movie 7", genre: "drama" } ];
const movie = [ { genre: "thriller" }, { genre: "comedy" }, { genre: "action" }, { genre: "drama" } ]; const FilterMethod01 = () => { const [genre, setGenre] = useState([""]); const [filteredGenre, setFilteredGenre] = useState([""]); const handleChange = e => { if (e.target.checked) { setGenre([...genre, e.target.value]); } else { setGenre(genre.filter(id => id !== e.target.value)); } }; useEffect(() => { setFilteredGenre( movieData.filter(movie => genre.some(category => category === movie.genre) ) ); }, [genre]); return ( <Fragment> <FormControl> <FormGroup> {movie.map(movie => ( <FormControlLabel control={<Checkbox onChange={handleChange} />} label={movie.genre} value={movie.genre} /> ))} </FormGroup> </FormControl> {filteredGenre .map((movie, index) => ( <Card style={{ background: "lightgreen", marginBottom: "5px" }}> <Typography gutterBottom variant="h6" noWrap> title: {movie.title} </Typography> <Typography gutterBottom variant="h6" noWrap> genre: {movie.genre} </Typography> </Card> ))} </Fragment> ); };
However, I have the following problems with this code:
All the mapped data
["movie 0", "movie 1", "movie 2", "movie 3"...]
doesn't appear by default. How can I get all the mapped data to appear by default?The mapped data only filters a single string (e.g.
{genre: ""}
) instead of an array of strings (e.g.{genre: ["thriller", "action"]}
). How can I select the "action" checkbox to trigger "movie 1", "movie 3", & "movie 6" to appear?
#Checkout my codesandbox here.#
If there are other better practices to achieve this result, please let me know as well. Thank you so much guys!
解决方案There are some fixes:
- remove ambiguous blank string:
const [genre, setGenre] = useState([]); const [filteredGenre, setFilteredGenre] = useState([]);
- if not filter any thing, just return all the movie data
- if filter, return any movie data which include genre of the filtered. Tricky part here is that movie data genre has multiple type, array and string, so a simple way to handle this is to wrap it in an array then flat
useEffect(() => { if (genre.length === 0) { setFilteredGenre(movieData) } else { setFilteredGenre( movieData.filter(movie => genre.some(category => [movie.genre].flat().includes(category)) ) ) } }, [genre])
Below is the forked codesandbox
这篇关于React如何使用多个复选框过滤数据数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!