我是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,可以更好地说明我的问题:
答案 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} />;
}
以下是摆脱过渡的一种方法。这会将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} />;
}