React如何使用多个复选框过滤数据数组 [英] React How to Filter Data Array using Multiple Checkbox

查看:74
本文介绍了React如何使用多个复选框过滤数据数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我打算通过以下代码选择不同的复选框来过滤数据:

  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></卡>))}</片段>);}; 

但是,此代码存在以下问题:

  1. 所有映射数据 [电影0",电影1",电影2",电影3" ...] 均未出现默认.如何使所有映射的数据默认显示?

  2. 映射的数据仅过滤单个字符串(例如 {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:

    1. 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?

    2. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆