Search code examples
reactjsarrayssortingmaterial-uicategories

Show Material UI chip on click of menu item


Sorry I don't know why the indentation on this code is so off. I want to show a chip every time a menu item is clicked, but with this current code it is showing a chip with all of the categories lumped together (ie "category 1category 2category 3" instead of "category 1". How can I set this up so that when Category 1 is clicked just the "Category 1" chip shows up, and when Category 2 is clicked just the "Category 2" chip shows up. Thanks.

        const categories = [
          'Category 1',
          'Category 2',
          'Category 3',
        ];
            
export default function Test() {
  const [selectedCategory, setSelectedCategory] = React.useState(null);
  const [anchorEl, setAnchorEl] = React.useState(null);
  const open = Boolean(anchorEl);
  const handleClick = (event) => {
    setAnchorEl(event.currentTarget);
  };
  const handleClose = () => {
    setAnchorEl(null);
  };

  const [expanded, setExpanded] = React.useState(false)
  const handleExpandClick = () => setExpanded(!expanded)

  const [showChip, setShowChip] = useState(false);

  const handleCategoryClick = () => {
    setShowChip(true);
    setSelectedCategory(categories);
    setAnchorEl(null);
  };

            
            return (
                              <Button
                                id="basic-button"
                                aria-controls={open ? 'basic-menu' : undefined}
                                aria-haspopup="true"
                                aria-expanded={open ? 'true' : undefined}
                                onClick={handleClick}
                              >
                                Categories
                              </Button>
                              <Menu
                                id="basic-menu"
                                anchorEl={anchorEl}
                                open={open}
                                onClose={handleClose}
                                MenuListProps={{
                                  'aria-labelledby': 'basic-button',
                                }}
                                
                              >
                                {categories.map((categories) => (
                                  <MenuItem
                                    key={categories}
                                    value={categories}
                                    onClick={handleClick}
                                  >
                                    {categories}
                                  </MenuItem>
                                ))}
        {selectedCategory && <Chip key={selectedCategory} label={selectedCategory} />}
                              </Menu>
            );

Solution

  • Not sure if I fully understand the desired result due to posted code seems partial, but if the goal is:

    when Category 1 is clicked just the "Category 1" chip shows up, and when Category 2 is clicked just the "Category 2" chip shows up

    Perhaps try have MenuItem pass the needed value to the handler handleCategoryClick:

      categories.map((categories) => (
        <MenuItem
          key={categories}
          value={categories}
          onClick={() => handleCategoryClick(categories)}
        >
          {categories}
        </MenuItem>
      ));
    

    In handleCategoryClick receive and set the related state with the clicked value:

      const handleCategoryClick = (categories) => {
        setShowChip(true);
        setSelectedCategory(categories);
        setAnchorEl(null);
      };
    

    Because Chip is already displayed conditionally and has wired up label with the state, it should display the right value when state selectedCategory is updated.

      selectedCategory && (
        <Chip
          key={selectedCategory}
          label={selectedCategory}
        />
      );