Как сохранить состояние после обновления страницы в React.js?

Допустим, у меня есть код, который устанавливает состояние для выбранного окна, выбранного на предыдущей странице:

this.setState({selectedOption: 5});

Есть ли способ иметь this.state.selectedOption заполненный 5 после обновления страницы?

Есть ли обратные вызовы, которые я могу использовать, чтобы сохранить это в localStorage, а затем сделать один большой setState или есть стандартный способ сделать что-то вроде этого?

Ответ 1

Поэтому моим решением было также установить localStorage при настройке моего состояния, а затем снова получить значение из localStorage внутри обратного вызова getInitialState следующим образом:

getInitialState: function() {
    var selectedOption = localStorage.getItem( 'SelectedOption' ) || 1;

    return {
        selectedOption: selectedOption
    };
},

setSelectedOption: function( option ) {
    localStorage.setItem( 'SelectedOption', option );
    this.setState( { selectedOption: option } );
}

Я не уверен, что это можно считать Anti-Pattern, но он работает, если не будет лучшего решения.

Ответ 2

Вы можете "сохранить" состояние, используя локальное хранилище, как предлагать Omar, но это нужно сделать, как только состояние будет установлено. Для этого вам нужно передать обратный setState функции setState и вам нужно сериализовать и десериализовать объекты, помещенные в локальное хранилище.

constructor(props) {
  super(props);
  this.state = {
    allProjects: JSON.parse(localStorage.getItem('allProjects')) || []
  }
}


addProject = (newProject) => {
  ...

  this.setState({
    allProjects: this.state.allProjects.concat(newProject)
  },() => {
    localStorage.setItem('allProjects', JSON.stringify(this.state.allProjects))
  });
}

Ответ 3

У нас есть приложение, которое позволяет пользователю устанавливать "параметры" на странице. Что мы делаем, это устанавливаем эти параметры в URL, используя React Router (вместе с History) и библиотеку, которая URI-кодирует объекты JavaScript в формат, который можно использовать в качестве строки запроса.

Когда пользователь выбирает опцию, мы можем поместить значение этого на текущий маршрут с помощью:

history.push({pathname: 'path/', search: '?' + Qs.stringify(params)});

pathname может быть текущим путем. В вашем случае params будет выглядеть примерно так:

{
  selectedOption: 5
}

Затем на верхнем уровне дерева React, React Router обновит props этого компонента реквизитом location.search который является закодированным значением, которое мы установили ранее, поэтому в componentWillReceiveProps будет что-то вроде:

params = Qs.parse(nextProps.location.search.substring(1));
this.setState({selectedOption: params.selectedOption});

Затем этот компонент и его дочерние элементы будут перерисованы с обновленной настройкой. Поскольку информация находится в URL-адресе, ее можно добавить в закладки (или отправить по электронной почте - это был наш случай использования), и обновление оставит приложение в том же состоянии. Это очень хорошо работает для нашего приложения.

React Router: https://github.com/reactjs/react-router

История: https://github.com/ReactTraining/history

Библиотека строк запроса: https://github.com/ljharb/qs

Ответ 4

Я считаю, что состояние предназначено только для просмотра информации, и данные, которые должны сохраняться за пределами состояния просмотра, лучше хранить в качестве подпорок. Параметры URL полезны, когда вы хотите иметь возможность ссылаться на страницу или предоставлять общий доступ к URL-адресу приложения, но в противном случае загромождать адресную строку.

Взгляните на Redux-Persist (если вы используете Redux) https://github.com/rt2zz/redux-persist

Ответ 6

Загрузите состояние из localStorage, если существует:

constructor(props) {
    super(props);           
    this.state = JSON.parse(localStorage.getItem('state'))
        ? JSON.parse(localStorage.getItem('state'))
        : initialState

переопределить this.setState, чтобы автоматически сохранять состояние после каждого обновления:

const orginial = this.setState;     
this.setState = function() {
    let arguments0 = arguments[0];
    let arguments1 = () => (arguments[1], localStorage.setItem('state', JSON.stringify(this.state)));
    orginial.bind(this)(arguments0, arguments1);
};

Ответ 7

Попробуйте сохранить значение в локальном хранилище и во время загрузки страницы получить значение из локального хранилища. Если у вас есть еще несколько значений, вы должны использовать избыточность для хранения данных.