如何使用useState正确传播对象

时间:2019-11-14 22:01:56

标签: reactjs react-hooks

当前在学校项目的明暗主题之间切换:(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);
};

我很好奇我应该如何用这个物体传播状态……谢谢!

2 个答案:

答案 0 :(得分:2)

您还需要将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
    }
  }
});

答案 1 :(得分:1)

如@Brian所述,您将必须明确地传播回您要编辑的对象。

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

您可以定义另一个变量以使其更具可读性。