反应应用程序本地存储未设置

Posted

技术标签:

【中文标题】反应应用程序本地存储未设置【英文标题】:react app local storage is not setting up 【发布时间】:2019-10-16 13:07:33 【问题描述】: 我正在尝试构建一个反应应用程序,我可以在其中看到类似于 *** 的通知。 当我打开两个不同的选项卡并打开 ***。我在两个不同的标签中看到通知。 但是当我点击那个通知图标时,数字消失了。 类似地,在另一个选项卡中,数字也会在不刷新页面的情况下消失。 我通过在 ie 和 chrome 中打开分析了 *** 网站 当我在 chrome 浏览器中单击信誉时,我看到发生网络呼叫,并且在 IE 浏览器中没有刷新数字消失。 我在本地存储和会话存储中看到了一些值。 不调用api可以实现吗,暂时可以用mock数据实现 我构建了标签 ui 并重定向到标签页 所以我在谷歌上找到了这个链接browser sessionStorage. share between tabs? 在我的反应代码中使用它,由于某种原因本地存储没有设置 它进入这个方法的另一个页面 但未添加存储键值。 通过放置控制台进行了调试,但它没有在窗口事件中打印任何内容。 你能告诉我如何解决它,表明我可以在不同的链接和标签之间共享会话。 在下面提供我的屏幕截图代码 sn-p 和沙箱

信誉通知场景 消息通知场景

https://codesandbox.io/s/material-demo-j5ec5

demo.js

  anotherPage = () => 
    console.log("redictToStepper --->");
    this.props.history.push("/anotherPage");

    if (!event) 
      console.log("window --->");
      event = window.event;
     // ie suq
    if (!event.newValue) return; // do nothing if no value to work with
    if (event.key == "getSessionStorage") 
      console.log("window --->");
      // another tab asked for the sessionStorage -> send it
      localStorage.setItem("sessionStorage", JSON.stringify(sessionStorage));
      // the other tab should now have it, so we're done with it.
      localStorage.removeItem("sessionStorage"); // <- could do short timeout as well.
     else if (event.key == "sessionStorage" && !sessionStorage.length) 
      // another tab sent data <- get it
      var data = JSON.parse(event.newValue);
      for (var key in data) 
        sessionStorage.setItem(key, data[key]);
      
    

    //listen for changes to localStorage
    if (window.addEventListener) 
      console.log("window --->");
      window.addEventListener("storage", "xxx", false);
     else 
      console.log("window --->");
      window.attachEvent("onstorage", "xxx");
    

    // Ask other tabs for session storage (this is ONLY to trigger event)
    if (!sessionStorage.length) 
      localStorage.setItem("getSessionStorage", "foobar");
      localStorage.removeItem("getSessionStorage", "foobar");
    
  ;

pageOne.js

 render() 
    const 
      showSearchResults,
      searchText,
      typeAhead,
      typeAheadMode,
      canEdit,
      value
     = this.state;

    const  classes  = this.props;

    return (
      <div className=classes.root>
        <AppBar position="static" color="default">
          <Tabs
            value=value
            onChange=this.handleChange
            indicatorColor="primary"
            textColor="primary"
            variant="scrollable"
            scrollButtons="auto"
          >
            <Tab label="Radiobutton One" />
            <Tab label="checkbox Two" />
          </Tabs>
        </AppBar>
        value === 0 && <TabContainer>Notification One</TabContainer>
        value === 1 && <TabContainer>Notification Two</TabContainer>
      </div>
    );
  

【问题讨论】:

我做了一些更改以在 codesandbox.io/s/material-demo-6ikw1 中获取本地和会话存储。你应该在点击的参数中传递事件和你想要做的存储类型。 你能否给你的代码更改提供 cmets,因为如果我在会话存储和本地存储中看到我没有看到添加的值 请立即查看。我可以在日志中看到会话存储。 @Ganeshchaitanya 嘿,但是每次我提交时,我都需要更新该选项卡组件中的通知,类似于 *** 通知,例如它们关闭浏览器并可以再次看到通知。在我的问题中提供了屏幕截图 您是否尝试过为此使用 websockets ? 【参考方案1】:

我无法确定您的 codepen 和 anotherPage 函数试图实现什么,所以我提供给您this codepen。在两个不同的窗口中打开它并查看共享的通知数量。

请注意,建议的本地存储解决方案仅适用于同一浏览器,因为浏览器不共享其本地存储。

这里如何在两个窗口之间同步您的本地存储,而无需进行任何远程 API 调用:

首先让添加一个事件监听器。第一个参数是事件类型(这里我们监听存储),第二个是回调。请注意,监听 storage 事件只能在两个窗口之间起作用(从一个窗口更新存储不会触发它自己的监听器):

  componentDidMount() 
    window.addEventListener("storage", this.handleStorageUpdate);
  

当您不再使用它(可能在 componentWillUnmount 上)时,请记住删除此侦听器,以防止任何膨胀。

  componentWillUnmount() 
    window.removeEventListener("storage", this.handleStorageUpdate);
  

现在让我们看看我们的听众。它将接收所有存储更改,但我们只想收听通知更改。当存储中的通知发生变化时,我们希望更新我们的组件状态以使用新值触发重新渲染:

  handleStorageUpdate = storageChange => 
    if (storageChange.key === "notifications") 
      this.setState(() => ( notifications: Number(storageChange.newValue) ));
    
  ;

所以现在,我们可以让两个窗口监听彼此所做的更改。

让我们给一个增加通知数量的方法:

 handleIncreaseNotification = () => 
    const notifications = this.state.notifications + 1;

    localStorage.setItem("notifications", notifications);

    this.setState(() => ( notifications ));
  ;

当增加通知的数量时,您将本地存储项设置为由另一个窗口使用。由于您没有收听自己对本地存储的更改,因此您需要将您的状态设置为这个新的通知数量。

由于您希望在打开窗口时直接查看通知计数,请记住在组件生命周期的最早状态之一获取本地存储的值:

  constructor(props) 
    super(props);

    const notifications = localStorage.getItem("notifications") || 0;
    this.state =  notifications: Number(notifications) ;
  

终于可以渲染整个组件了:

  render() 
    const  notifications  = this.state;
    return (
      <div>
        <div> I have notifications notifications</div>
        <button onClick=this.handleIncreaseNotification>increase</button>
      </div>
    );
  

【讨论】:

嘿,使用模拟数据...你能让它适用于不同的浏览器吗...稍后使用模拟数据我将构建 api @zizi 本地存储不在浏览器之间共享,您不能使用模拟数据来使其按需要工作,如果您需要通知状态在浏览器之间持续存在,则需要 API。 @JakeHolzinger 是的,对于 taht API,你能给我一个模拟 dta,以便我将使用它构建一个 api,现在我将使用模拟 dta 对其进行测试......这样我就可以做一个带有模拟数据的 poc

以上是关于反应应用程序本地存储未设置的主要内容,如果未能解决你的问题,请参考以下文章

Docker compose 未正确复制文件以运行反应应用程序

反应本地存储

如何将 TextInput 的值存储到本地存储并在应用程序以本机反应启动时获取它们?

将我的本地反应应用程序文件发送到 VsCode 中的 Github 存储库的命令是啥?

反应并将 jwt 令牌存储在本地存储中

如何在反应查询中存储本地状态?