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

IT技术 javascript html reactjs redux local-storage
2021-04-04 05:36:44
  • 我正在尝试构建一个 React 应用程序,我可以在其中看到类似于 stackoverflow 的通知。
  • 当我打开两个不同的选项卡并打开 stackoverflow 时。我在两个不同的选项卡中看到通知。
  • 但是当我单击该通知图标时,数字会出现。
  • 同样,在另一个选项卡中,数字也会消失而不刷新页面。
  • 我通过在 ie 和 chrome 中打开来分析 stackoverflow 站点
  • 当我在 chrome 浏览器中单击声誉时,我看到网络呼叫正在发生,并且在 IE 浏览器中没有刷新数字显示
  • 我在本地存储和会话存储中看到了一些值。
  • 是否可以不调用api来实现,暂时我们可以使用模拟数据来实现
  • 我构建标签 ui 并重定向到标签页
  • 所以我谷歌并找到了这个链接浏览器 sessionStorage。在标签之间共享?
  • 在我的react代码中使用它,由于某种原因本地存储没有设置
  • 它进入这个方法 anotherPage
  • 但存储键值没有添加。
  • 通过放置控制台进行调试,但它不会在窗口事件中打印任何内容。
  • 你能告诉我如何修复它表明我可以在不同的链接和选项卡之间共享会话。
  • 在下面提供我的屏幕截图代码片段和沙箱

信誉通知方案 消息通知方案在此处输入图片说明 在此处输入图片说明

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

演示.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>
    );
  }
1个回答

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

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

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

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

  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>
    );
  }
@zizi 本地存储不在浏览器之间共享,您不能使用模拟数据使其按需要工作,如果您需要通知状态在浏览器之间保持不变,则需要一个 API。
2021-06-02 05:36:44
@JakeHolzinger 是的,对于 taht API,你能给我一个模拟 dta,这样我就可以使用它来构建一个 api,现在我将用模拟 dta 测试它......这样我就可以用模拟数据做一个 poc
2021-06-04 05:36:44
嘿,使用模拟数据……你能不能让它适用于不同的浏览器……稍后使用模拟数据我将构建 api
2021-06-20 05:36:44