Как сохранить состояние после обновления страницы в 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
Ответ 5
2019 Ответ
Используйте хук из этой библиотеки - https://github.com/donavon/use-persisted-state
Ответ 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
Попробуйте сохранить значение в локальном хранилище и во время загрузки страницы получить значение из локального хранилища. Если у вас есть еще несколько значений, вы должны использовать избыточность для хранения данных.