React How to Filter Data Array using Multiple Checkbox

ε祈祈猫儿з 提交于 2021-01-29 07:10:16

问题


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!


回答1:


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




回答2:


Here's some suggestions, you should keep consistent on declaring arrays of object, and the array inside.

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: ["romance"] 
  },
  {
    title: "movie 5",
    genre: ["horror", "drama"]
  },
  {
    title: "movie 6",
    genre: ["comedy"]
  },
  {
    title: "movie 7",
    genre: []
  }
];

Maybe it could solve the logic to loop inside the array.

*CMIIW because I'm new :D



来源:https://stackoverflow.com/questions/63259655/react-how-to-filter-data-array-using-multiple-checkbox

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!