如何在页面刷新中访问状态值?

时间:2019-04-02 12:38:48

标签: reactjs material-ui next.js

我正在我的项目中实现时间跟踪器。当我启动跟踪器时,我将该跟踪器值存储到状态中,而在暂停该跟踪器时,则将该值更改为状态。但是,当我刷新页面时,我没有得到上次更新的状态值。那么如何获取页面刷新的状态值?

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 个答案:

答案 0 :(得分:3)

如果您希望状态在刷新后仍然存在,则需要将状态存储在componentWillUnmount中的localStorage中,然后将状态重置为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)
  }

但是,请记住,在某些浏览器(例如iOS中的Safari)中,onbeforeunload没有正确实现。因此,您可能会因此而面临一些问题。这是事件https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onbeforeunload#Browser_compatibility的兼容性列表。