реагировать приложение локальное хранилище не настраивается - PullRequest
6 голосов
/ 31 мая 2019
  • Я пытаюсь создать приложение реакции, в котором я вижу уведомления, похожие на stackoverflow.
  • когда я открываю две разные вкладки и открываю stackoverflow. Я вижу уведомления на двух разных вкладках.
  • , но когда я нажимаю на значок уведомления, цифры появляются.
  • аналогично в другой вкладке также исчезает число без обновления страницы.
  • Я проанализировал сайт stackoverflow, открыв в ie и chrome
  • когда я нажимаю на репутацию в браузере Chrome, я вижу, что происходит сетевой вызов, и в браузере IE без обновления цифр .
  • Я вижу некоторые значения в локальном хранилище и хранилище сеанса.
  • возможно ли достичь без использования API-вызовов, на данный момент мы можем достичь с помощью фиктивных данных
  • Я создаю интерфейс вкладок и перенаправляю на страницу вкладок
  • поэтому я гуглю и нашел эту ссылку браузер сеанса хранения. поделиться между вкладками?
  • использовал его в моем коде реакции, по какой-то причине локальное хранилище не настраивается
  • Это входит в этот метод другой страницы
  • но значение ключа хранилища не добавляется.
  • отлажено с помощью консолей, но в событиях окна ничего не печатается.
  • Подскажите, как это исправить, покажите, что я могу разделить сеанс между разными ссылками и вкладками.
  • предоставив мой фрагмент кода скриншота и песочницу ниже

сценарий репутационных уведомлений enter image description here сценарий уведомления о сообщении enter image description here

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>
    );
  }

1 Ответ

3 голосов
/ 05 июня 2019

У меня были проблемы с определением того, чего пытался достичь ваш codepen и функция anotherPage, поэтому я предоставляю вам этот codepen . Откройте его в двух разных окнах и посмотрите общее количество уведомлений.

Обратите внимание, что предлагаемое решение Local Storage работает только в том же браузере, поскольку браузеры не используют свои локальные хранилища.

Здесь, как синхронизировать локальное хранилище между двумя окнами, не делая удаленного вызова 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>
    );
  }
...