首页 > 解决方案 > 如何使用 useState 正确传播对象

问题描述

目前正在为一个学校项目在明暗主题之间切换:(https://codesandbox.io/s/stack-overflow-dark-theme-light-theme-xh0s4)。但是,只要用户使用按钮进行切换,主题对象就会被覆盖(例如,没有主要颜色和次要颜色)。状态和功能看起来像这样......

const [theme, setTheme] = useState({
  palette: {
    primary: {
      main: "#FF0000",
      light: "#E7F6E7",
      contrastText: "#FFFFFF"
    },
    secondary: {
      main: "#FFFFFF"
    },
    type: "light"
  }
});

const toggleTheme = () => {
  let newPaletteType = theme.palette.type === "light" ? "dark" : "light";
  setTheme({
    ...theme,
    palette: {
      type: newPaletteType
    }
  });
  console.log(theme);
};

我很好奇我应该如何用这个对象传播状态......谢谢!

标签: reactjsreact-hooks

解决方案


您还需要将palette对象传播回自身。

const toggleTheme = () => {
  let newPaletteType = theme.palette.type === "light" ? "dark" : "light";
  setTheme({
    ...theme,
    palette: {
      ...theme.palette, // here
      type: newPaletteType
    }
  });
};

当您修改对象的一个​​键时,如果要保留它们,则需要替换其他键。当您使用扩展运算符时,您实际上不再是修改原始对象,而是根据原始对象的值创建一个新对象。然而,在嵌套对象上,仅仅做父对象是不够的。

因此,例如,如果您更改了 中的一个键primary,则需要在所有三个嵌套级别上执行此操作。

setTheme({
  ...theme,
  palette: {
    ...theme.palette,
    primary: {
      ...theme.palette.primary,
      //change value in primary
    }
  }
});

推荐阅读