首页 > 解决方案 > 使用自定义挂钩重新渲染应用程序不起作用

问题描述

我就我从事的一个小项目寻求建议。当我的状态发生变化时,我在重新渲染/重新加载应用程序时遇到问题。当我将 useState 更改为使用会话存储的自定义挂钩时,出现了问题。有钩子的代码:

const useStateWithSessionStorage = (localStorageKey) => {
  const [value, setValue] = React.useState(
    JSON.parse(sessionStorage.getItem(localStorageKey)) || {
      screen: "signin",
      loading: false,
      user: null,
      response: null,
    }
  );

  React.useEffect(() => {
    sessionStorage.setItem(localStorageKey, JSON.stringify(value));
  }, [value]);

  return [value, setValue];
};

这是我的 App.js:

export default function App() {
  const [appState, setAppState] = useStateWithSessionStorage("appState");

  const renderApp = () => {
    if (appState.screen == "signin") return <Signin />;
    if (appState.screen == "hub") return <Hub />;
  };

 return <div className="App">{renderApp()}</div>;
}

我还尝试将屏幕值加载到另一个状态,这将在 useEffect 中重新渲染,但是没有成功。

renderApp 函数返回 或 。登录组件仅显示电子邮件和密码输入,这些值是通过使用 sql 的烧瓶端点发送的。

该端点更新 appState。具体来说,它将 appState.screen 更改为“集线器”。

有我提到的问题。尽管状态发生了变化(在 JSON.stringify 显示的页面上可见)。该应用程序不会重新渲染并停留在组件上。为了正常工作并显示,我总是必须刷新页面。

我对这个很新,有人能给我建议吗?

标签: javascriptreactjs

解决方案


当某些组件更改会话键值时,您将需要收听Window: storage 事件以得到通知:

const useStateWithSessionStorage = (localStorageKey) => {
  const [value, setValue] = React.useState(
    JSON.parse(sessionStorage.getItem(localStorageKey)) || {
      screen: "signin",
      loading: false,
      user: null,
      response: null,
    }
  );

  React.useEffect(()=> {
    const onStorage = () => {
       const data = JSON.parse(sessionStorage.getItem(localStorageKey)));
       if(data.screen !== value.screen) { /* data changes*/
          setValue(data);
       }
    }
    window.addEventListener('storage', onStorage);
    return () => window.removeEventListener("storage", onStorage);
  }, []);

  React.useEffect(() => {
    sessionStorage.setItem(localStorageKey, JSON.stringify(value));
  }, [value]);

  

  return [value, setValue];
};

推荐阅读