Chrome 存储 API 在 useState 中设置状态

Chrome Storage API to set state in useState

如何使用 Chrome 存储 API 设置我的 React 应用程序的初始状态?

据我了解 chrome.storage.sync.get() 是基于回调的,没有 return 值。

我试过:

chrome.storage.sync.get("tabs", (result) => {
  const [tabs, setTabs] = useState(result.tabs);
});

但是这给出了一个错误,即 useState 声明不能嵌套在函数中。

我也试过:

var init_tabs = null;
chrome.storage.sync.get("tabs", (result) => {
  init_tabs = result.tabs
});
const [tabs, setTabs] = useState(init_tabs);

不过这个好像也没有影响。

我正在尝试做的事情是否可行?

编辑

您可以使用 new Promise() 来保证回复。

const [tabs, setTabs] = useState(async () => {
  var promise = new Promise((resolve) => {
    chrome.storage.sync.get("tabs", (result) => {
      resolve(result.tabs);
    });
  });

  return await promise;
});

问题

var init_tabs = null;
chrome.storage.sync.get("tabs", (result) => {
  init_tabs = result.tabs
});
const [tabs, setTabs] = useState(init_tabs);

由于以下几个原因,这不起作用:

  1. 来自 useState 反应钩子的状态只被初始化一次。
  2. init_tabs 会在每个渲染周期重置,chrome.storage.sync.get 会在每个渲染周期调用,但是 init_tabs = result.tabs 会毫无结果,因为它可能会在某些 之后发生渲染周期。

解决方案

我不确定你的 tabs 状态对象的形状是什么,你的基于 promise 的状态初始化器看起来可以工作,但是加载状态的更标准的反应方式(即惯用的)是在组件安装时在 useEffect 挂钩中执行数据“fetch/load”。它使用了很多与您的编辑相同的逻辑,但更传统,不需要包含在承诺中。

const [tabs, setTabs] = useState(/* ... some initial state ... */);

useEffect(() => {
  chrome.storage.sync.get("tabs", (result) => {
    setTabs(result.tabs);
  });
}, []); // <-- empty dependency array to run effect callback once "onMount"

从这里开始,如何在 tabs 状态填充时最好地处理渲染 UI 取决于您。