如何防止MaterialUI切换动画?

时间:2020-07-30 02:29:34

标签: reactjs google-chrome-extension material-ui

我是React的新手,正在使用它进行Chrome扩展。

当前,我在弹出页面中使用MaterialUI中的Switch组件。我现在如何保存其状态是通过将每次更改的状态存储在chrome.storage.local API中。当我单击返回到弹出窗口时,我仅使用useEffect钩子并从chrome.storage.local中获取状态并将其作为参数传递给setState()。

我的问题是,当您重新打开弹出窗口时,切换按钮会非常短暂地从关闭变为激活(就像您手动切换一样)。我知道这是因为我正在这样做(例如,每次打开弹出窗口时都将切换状态初始化为false),但是目前我很困惑地要这样做。谁能帮我吗?感谢您的阅读!

MySwitchComponent.jsx

import React, { useState } from "react";
import { withStyles } from "@material-ui/core/styles";
import { Switch } from '@material-ui/core/';

const StyledSwitch = withStyles({
  root: {
    position: 'relative',
    marginTop: '20px',
    marginLeft: '90px'
  },
})(Switch);

export default function NewSwitch() {
  const [state, setState] = React.useState(false)

  const handleChange = (event) => {
    setState(event.target.checked);
    chrome.storage.local.set({auto_delete_toggle: event.target.checked });
  }

  React.useEffect(() => {
    chrome.storage.local.get(null, function(res){
      setState(res.auto_delete_toggle);
    })
  });

  return (
    <StyledSwitch
    checked={state}
    onChange={handleChange}
    > 
    </StyledSwitch>)
 
}

我的popup.js仅呈现所有封装在popup.html中的组件。此外,chrome.storage.local.get是异步的。

编辑: 这是一个GIF,可以更好地说明我的问题: Toggle Button unwanted reanimation

1 个答案:

答案 0 :(得分:0)

首先,这是一个再现您问题的沙盒。我使用了mockAsyncStorage(由window.localStorage支持)来模拟异步chrome.storage.local.get。您可以通过单击开关以选中它,然后刷新页面来查看不希望的过渡。

import React from "react";
import Switch from "@material-ui/core/Switch";
import mockAsyncStorage from "./mockAsyncStorage";
export default function App() {
  const [checked, setChecked] = React.useState(false);

  const handleChange = event => {
    setChecked(event.target.checked);
    mockAsyncStorage.set({ auto_delete_toggle: event.target.checked });
  };

  React.useEffect(() => {
    mockAsyncStorage.get(null, function(res) {
      setChecked(
        res.auto_delete_toggle === undefined ? false : res.auto_delete_toggle
      );
    });
  }, []);
  return <Switch checked={checked} onChange={handleChange} />;
}

Edit Switch async init

以下是摆脱过渡的一种方法。这会将checked初始化为undefined,并且在它仍为undefined时,它返回null而不是开关,因此在知道开关的适当初始状态之前不会呈现任何内容。

import React from "react";
import Switch from "@material-ui/core/Switch";
import mockAsyncStorage from "./mockAsyncStorage";
export default function App() {
  const [checked, setChecked] = React.useState(undefined);

  const handleChange = event => {
    setChecked(event.target.checked);
    mockAsyncStorage.set({ auto_delete_toggle: event.target.checked });
  };

  React.useEffect(() => {
    mockAsyncStorage.get(null, function(res) {
      setChecked(
        res.auto_delete_toggle === undefined ? false : res.auto_delete_toggle
      );
    });
  }, []);
  if (checked === undefined) {
    return null;
  }
  return <Switch checked={checked} onChange={handleChange} />;
}

Edit Switch async init