代码之家  ›  专栏  ›  技术社区  ›  Temp Account

如何在不创建新密钥的情况下动态更改映射中的项目?

  •  1
  • Temp Account  · 技术社区  · 3 月前

    我有 following sandbox

    import "./styles.css";
    import { useEffect, useState } from "react";
    
    export default function App() {
      interface filter {
        company: boolean;
        gender: boolean;
      }
      const [people, setPeople] = useState<filter>({
        company: false,
        gender: false,
      });
    
        useEffect(() => {
        console.log(people);
      }, [people]);
    
    
      const toggleMenu = (menuItem: keyof typeof people) => {
        setPeople({ ...people, menuItem: !people[menuItem] });
      };
    
    
      return (
        <div className="App">
                        <button
                    className="flex flex-row justify-center w-full"
                    onClick={() => toggleMenu("company")}
                  >
    Click me 
    </button>
        </div>
      );
    }
    

    这个 toggleMenu 函数似乎无法正常工作。这个想法是传递一个任意的键(例如“company”),并让它切换值。相反,我得到以下输出:

    {company: false, gender: false, menuItem: true}

    我想要什么:

    {company: true, gender: false}

    我尝试了上面的代码,但没想到会在我的地图中看到一个新的密钥。。。只需要更新现有密钥。

    1 回复  |  直到 3 月前
        1
  •  1
  •   cchamberlain    3 月前

    问题是您正在添加的新密钥 menuItem 给你的人对象。您需要在键周围添加括号:

    const toggleMenu = (menuItem: keyof typeof people) => {
      setPeople({ ...people, [menuItem]: !people[menuItem]
      });
    };
    

    我已经将您的代码重构为可读性更强的版本,并实现了修复:

    import { useEffect, useState } from "react";
    
    interface Filter {
      company: boolean;
      gender: boolean;
    }
    
    export const App = () => {
      const [filter, setFilter] = useState<Filter>({
        company: false,
        gender: false,
      });
    
      useEffect(() => {
        console.log(filter);
      }, []);
    
      const toggleMenu = (filterKey: keyof Filter) => {
        setFilter({ ...filter, [filterKey]: !filter[filterKey] });
      };
    
      return (
        <div className="App">
          <button
            type="button"
            className="flex flex-row justify-center w-full"
            onClick={() => {
              toggleMenu("company");
            }}
          >
            Click me
          </button>
        </div>
      );
    };