简体   繁体   English

useEffect 不监听 localStorage

[英]useEffect does not listen for localStorage

I'm making an authentication system and after backend redirects me to the frontend page I'm making API request for userData and I'm saving that data to localStorage.我正在制作一个身份验证系统,在后端将我重定向到前端页面后,我正在为 userData 发出 API 请求,并将该数据保存到 localStorage。 Then I'm trying to load Spinner or UserInfo.然后我尝试加载 Spinner 或 UserInfo。

I'm trying to listen for the localStorage value with useEffect, but after login I'm getting 'undefined'.我正在尝试使用 useEffect 监听 localStorage 值,但登录后我得到“未定义”。 When the localStorage value is updated useEffect does not run again and Spinner keeps spinning forever.当 localStorage 值更新时,useEffect 不会再次运行,并且 Spinner 会一直旋转。

I have tried to do: JSON.parse(localStorage.getItem('userData')) , but then I got a useEffect infinite loop.我试过这样做: JSON.parse(localStorage.getItem('userData')) ,但后来我得到了一个 useEffect 无限循环。

Only when I'm refreshing the page does my localStorage value appear and I can display it instead of Spinner.只有当我刷新页面时,我的 localStorage 值才会出现,并且我可以显示它而不是 Spinner。

What I'm doing wrong?我做错了什么?

Maybe there is a better way to load userData when it's ready?准备好后,也许有更好的方法来加载 userData ?

I'm trying to update DOM in correct way?我正在尝试以正确的方式更新 DOM?

Thanks for answers;)感谢您的回答;)

import React, { useState, useEffect } from 'react';
import { Spinner } from '../../atoms';
import { Navbar } from '../../organisms/';
import { getUserData } from '../../../helpers/functions';

const Main = () => {
  const [userData, setUserData] = useState();
  useEffect(() => {
    setUserData(localStorage.getItem('userData'));
  }, [localStorage.getItem('userData')]);

  return <>{userData ? <Navbar /> : <Spinner />}</>;
};

export default Main;

It would be better to add an event listener for localstorage here.最好在此处为 localstorage 添加事件侦听器。

useEffect(() => {
  function checkUserData() {
    const item = localStorage.getItem('userData')

    if (item) {
      setUserData(item)
    }
  }

  window.addEventListener('storage', checkUserData)

  return () => {
    window.removeEventListener('storage', checkUserData)
  }
}, [])

The solution is to use this structure:解决方案是使用这种结构:

useEffect(() => {
// Other functions

window.addEventListener("storage", () => {
  // When storage changes refetch
  refetch();
});
return () => {
  // when the component unmounts remove the event listener
  window.removeEventListener("storage");
};

}, []); }, []);

Event listener to 'storage' event won't work in the same page “存储”事件的事件侦听器在同一页面中不起作用

The storage event of the Window interface fires when a storage area (localStorage) has been modified in the context of another document. Window 接口的存储事件在另一个文档的上下文中修改了存储区域 (localStorage) 时触发。

https://developer.mozilla.org/en-US/docs/Web/API/Window/storage_event https://developer.mozilla.org/en-US/docs/Web/API/Window/storage_event

  • "Maybe there is a better way to load userData when it's ready?" “也许有更好的方法在准备好后加载 userData?”

You could evaluate the value into localStorage directly instead passing to state.您可以将值直接评估为 localStorage,而不是传递给 state。

const Main = () => {
  if (localStage.getItem('userData')) {
    return (<Navbar />);
  }
  else {
    return (<Spinner />);
  }
};

If there is a need to retrieve the userData in more components, evaluate the implementation of Redux to your application, this could eliminate the usage of localStorage, but of course, depends of your needs.如果需要在更多组件中检索userData ,请评估 Redux 对您的应用程序的实现,这可以消除 localStorage 的使用,但当然,这取决于您的需要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM