sessionStorage更新时useMemo不起作用

时间:2020-08-01 14:27:20

标签: javascript reactjs react-hooks

我有一个应用程序,其标题包含应在用户登录时显示的图标。我将登录信息保留在sessionStorage中,但是当它更改时,不会再次呈现我的组件。我尝试为此使用useEffectuseMemo,但它不起作用。

更新部分:

const isLoggedIn = useMemo(() => sessionStorage.getItem('isLogged'), [sessionStorage.getItem('isLogged')]);

用法:

      {isLoggedIn === 'true' ? ['left'].map((anchor) => (
        ...some jsx
      )) : null}

sessionStorage的值是一个字符串:“ false”或“ true”。

我有路由和恒定的标头,标头不是路由的一部分,因此当它更改时,我的标头不会重新渲染,因此我尝试使用useMemo。

4 个答案:

答案 0 :(得分:1)

sessionStorage不是观察者对象,您必须将当前身份验证状态存储到变量或React状态中,并在组件中使用该变量。并且,在对用户进行身份验证时,应将变量更新为true,并在用户注销时将其更改为false。 要实现我所说的内容,您可以通过以下方式获得帮助:

  1. Redux
  2. 反应上下文

您可以从头开始或使用React-hooks-global-state

自行实现React上下文

答案 1 :(得分:1)

根据通过评论获得的澄清发表我的答案。

如果您使用的是Redux

我建议将用户登录的信息存储redux store中,并通过 connect 连接到隔离的标头组件HOC和mapStateToProps。每当您更新(成功登录后)用户登录状态时,组件都会侦听store更新。

如果没有使用context,则可以使用React redux方法

// Declare it outside of your App component/any other file and export it
const GlobalState = React.createContext();


// Declare state variable to store user logged in info inside of your App component
const [isLoggedIn, setIsLoggedIn] = useState(false);

// Add them to context to access anywhere in your components via useContext
// In App render or where you have route mapping
<GlobalState.Provider value={{
  isLoggedIn,
  setIsLoggedIn
}}>
  ....
</GlobalState.Provider>

// Update the status using setIsLoggedIn upon successful login where you are making login call

// In your Header get it via useContext
const context = useContext(GlobalState);

`context.isLoggedIn` is what you need.

// You can use useEffect/useMemo approach to get the login status updates

详细了解React contextuseContext

答案 2 :(得分:0)

UseMemo用于记忆计算值。您应该使用useCallback.useCallback用于记忆函数引用。 请参阅this

const isLoggedIn = useCallback(() => sessionStorage.getItem('isLogged'), [sessionStorage.getItem('isLogged')]);

答案 3 :(得分:0)

您可以尝试将sessionStorage数据放入State并更新该状态吗?据我所知,react不会知道会话存储。因此,即使您直接更改对sessionStorage中数据的操作,也不会更新您的UI。

let [storeData, setStoreData] = useState(true);

let isLoggedIn = useMemo(() => ({ sessionData: storeData }), [storeData]);

 {isLoggedIn === 'true' ? ['left'].map((anchor) => (
    ...some jsx
  )) : null}


 <button
   onClick={() => {
      sessionStorage.setItem("isLogged", !storeData);
      setStoreData(sessionStorage.getItem("isLogged"));
   }} > Update Store </button>