#reactjs #material-ui #next.js
#reactjs #материал-пользовательский интерфейс #next.js
Вопрос:
Я внедряю time tracker в свой проект. Когда я запускаю свой трекер, я сохраняю это значение трекера в состояние, а при приостановке этого трекера затем меняю это значение на состояние. Но когда я обновляю страницу, я не получаю последнее обновленное значение состояния. Итак, как я могу получить значение состояния при обновлении страницы?
const React = require("react");
const ms = require("pretty-ms");
class TaskTimer extends React.Component {
constructor(props) {
super(props);
this.state = {
time: 0,
isOn: false,
start: 0
};
this.startTimer = this.startTimer.bind(this);
this.stopTimer = this.stopTimer.bind(this);
this.resetTimer = this.resetTimer.bind(this);
}
startTimer() {
this.setState({
isOn: true,
time: this.state.time,
start: Date.now() - this.state.time
});
this.timer = setInterval(
() =>
this.setState({
time: Date.now() - this.state.start
}),
1
);
}
stopTimer() {
this.setState({ isOn: false });
clearInterval(this.timer);
}
resetTimer() {
this.setState({ time: 0, isOn: false });
}
render() {
let start =
this.state.time == 0 ? (
<button onClick={this.startTimer}>start</button>
) : null;
let stop =
this.state.time == 0 || !this.state.isOn ? null : (
<button onClick={this.stopTimer}>stop</button>
);
let resume =
this.state.time == 0 || this.state.isOn ? null : (
<button onClick={this.startTimer}>resume</button>
);
let reset =
this.state.time == 0 || this.state.isOn ? null : (
<button onClick={this.resetTimer}>reset</button>
);
return (
<div>
<h3>timer: {ms(this.state.time)}</h3>
{start}
{resume}
{stop}
{reset}
</div>
);
}
}
module.exports = TaskTimer;
Кто-нибудь, пожалуйста, подскажите мне, как получить значение состояния при обновлении страницы?
Ответ №1:
если вы хотите, чтобы ваше состояние сохранялось после обновления, тогда вам нужно будет сохранить состояние в localStorage в componentWillUnmount
, а затем сбросить состояние до того, в каком оно было раньше componentDidMount
. Это
componentDidMount() {
const stateObject = JSON.parse(localStorage.getItem("state"));
this.setState(stateObject);
}
componentWillUnmount() {
localStorage.setItem("state", JSON.stringify(this.state));
}
Однако это может привести к неожиданным результатам, если componentWillUnmount не может быть вызван во время обновления. Таким образом, более надежным (но менее производительным) методом было бы обновлять состояние до localStorage каждый раз, когда вы обновляете свое состояние. Это можно сделать, вставив код componentDidUpdate
.
componentDidUpdate(prevProps, prevState) {
if(prevState != this.state) {
localStorage.setItem("state", this.state);
}
}
Обновить:
После некоторых исследований я нашел событие beforeunload
, которое могло бы работать довольно эффективно.
onUnload = (event) => {
localStorage.setItem("state", JSON.stringify(this.state)
}
componentDidMount() {
window.addEventListener("beforeunload", this.onUnload)
}
componentWillUnmount() {
window.removeEventListener("beforeunload", this.onUnload)
}
Однако имейте в виду, что onbeforeunload неправильно реализован в некоторых браузерах (например, Safari в iOS). Таким образом, вы можете столкнуться с некоторыми проблемами в связи с этим. Это список совместимости для события https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onbeforeunload#Browser_compatibility .
Комментарии:
1. Я не сохраняю значение состояния в локальном хранилище из-за изменения значения моего состояния каждую секунду. Основная проблема заключается в том, что при запуске таймера и обновлении страницы в это время значение состояния повторно инициализируется нулем. Итак, как я могу получить последнее значение состояния таймера при обновлении страницы.
2. Из вашего кода похоже, что ваше состояние меняется тысячу раз в секунду.
setInterval
принимает второй аргумент в миллисекундах.3. Кроме того, единственный способ гарантировать, что определенное значение остается в области видимости после обновления, — это либо сохранить его в localStorage, либо сохранить как параметр URL. Однако это означало бы, что ваш URL-адрес будет меняться каждую секунду, что может сильно отвлекать пользователя.
4. Я думаю, вы могли бы использовать библиотеку под названием lscache ( github.com/pamelafox/lscache ). Вы можете сохранить значение состояния на некоторое время и использовать его после.
5. @Pedrinhow Lscache означает локальный кеш хранилища .. он будет делать то же самое, о чем я упоминал, за исключением того, что он будет абстрагирован за библиотекой