ReactJS Stopwatch,如何处理本地存储数据

时间:2019-02-09 12:01:22

标签: javascript reactjs

我有我在其中计算时间的组件(秒表)。一切正常。启动,停止时钟复位。我想添加一些功能,当我停止时钟(handleTimerStop时,如果我关闭浏览器并想返回并想在我的时钟暂停的地方开始,则将当前状态设置为localstorage。因此,当我停止时钟项目时,将其设置为localstorage,但是当我想重新启动时钟时,它不会从本地存储中获取数据,而是从头开始。能否请你帮忙?如果有人可以优化我的代码,那也是很棒的,因为我觉得它可以做得更好。

谢谢

    import React, { Component } from "react";

export default class Timer extends Component {
  constructor(props) {
    super(props);
    this.state = {
      timerStarted: false,
      timerStopped: true,
      hours: 0,
      minutes: 0,
      seconds: 0
    };
  }
  componentDidMount() {
    if (!localStorage.getItem("sec") === null) {
      this.setState({
        seconds: localStorage.getItem("sec")
      });
    }
    if (!localStorage.getItem("min") === null) {
      this.setState({
        seconds: localStorage.getItem("min")
      });
    }
    if (!localStorage.getItem("hour") === null) {
      this.setState({
        seconds: localStorage.getItem("hours")
      });
    }
  }

  handleTimerStart = e => {
    e.preventDefault();

    if (localStorage.getItem("sec") === null) {
      this.setState({
        seconds: 0
      });
    } else {
      this.setState({
        seconds: localStorage.getItem("sec")
      });
    }
    if (localStorage.getItem("min") === null) {
      this.setState({
        minutes: 0
      });
    } else {
      this.setState({
        minutes: localStorage.getItem("min")
      });
    }
    if (localStorage.getItem("hour") === null) {
      this.setState({
        hours: 0
      });
    } else {
      this.setState({
        hours: localStorage.getItem("hour")
      });
    }

    if (this.state.timerStopped) {
      this.timer = setInterval(() => {
        this.setState({ timerStarted: true, timerStopped: false });
        if (this.state.timerStarted) {
          if (this.state.seconds >= 60) {
            this.setState(prevState => ({
              minutes: prevState.minutes + 1,
              seconds: localStorage.getItem("sec")
            }));
          }
          if (this.state.minutes >= 60) {
            this.setState(prevState => ({
              hours: prevState.hours + 1,
              minutes: localStorage.getItem("min"),
              seconds: localStorage.getItem("sec")
            }));
          }
          this.setState(prevState => ({ seconds: prevState.seconds + 1 }));
        }
      }, 1000);
    }
  };

  handleTimerStop = () => {
    this.setState({ timerStarted: false, timerStopped: true });
    clearInterval(this.timer);
    localStorage.setItem("sec", this.state.seconds);
    localStorage.setItem("min", this.state.minutes);
    localStorage.setItem("hour", this.state.hours);
  };

  handelResetTimer = () => {
    this.setState({
      timerStarted: false,
      timerStopped: true,
      hours: 0,
      minutes: 0,
      seconds: 0
    });
  };
  render() {
    return (
      <div className="container">
        <h2 className="text-center"> React Based Timer </h2>
        <div className="timer-container">
          <div className="current-timer">
            {this.state.hours +
              ":" +
              this.state.minutes +
              ":" +
              this.state.seconds}
          </div>
          <div className="timer-controls">
            <button className="btn btn-success" onClick={this.handleTimerStart}>
              Start Timer
            </button>
            <button className="btn btn-alert" onClick={this.handleTimerStop}>
              Stop Timer
            </button>
            <button className="btn btn-info"> Capture Time </button>
            <button className="btn btn-danger" onClick={this.handelResetTimer}>
              {" "}
              Reset!{" "}
            </button>
          </div>
        </div>
      </div>
    );
  }
}

2 个答案:

答案 0 :(得分:0)

这些比较是您的问题。

struct Matrix4 {

    // ...

    void SetScale( Vector3 v ) {
        identity();
        m[0] = v.x; m[5] = v.y; m[10] = v.z;
    }

    void SetTranslate( Vector3 v ) {
        identity();
        m[12] = v.x; m[13] = v.y; m[14] = v.z;
    }

    void SetRotate( Vector3 v, float rad ) {
        identity();

        float c = cosf(rad);
        float s = sinf(rad);
        float x = v.x, y = v.x, z = v.z;

        m[0] = x*x*(1.0f-c)+c;   m[1] = x*y*(1.0f-c)-z*s; m[2]  = x*z*(1.0f-c)+y*s;
        m[4] = y*x*(1.0f-c)+z*s; m[5] = y*y*(1.0f-c)+c;   m[6]  = y*z*(1.0f-c)-x*s;
        m[8] = z*x*(1.0f-c)-y*s; m[9] = z*y*(1.0f-c)+x*s; m[10] = z*z*(1.0f-c)+c;
    }

    // ...

}

答案 1 :(得分:0)

这不是您的具体问题的答案,而是imo。一种更好的代码处理方法

此实现是

  • 与渲染间隔无关,
  • 仅在启动/停止/重置时将其写入localStorage
  • 并且不会失去同步(即使根本无法渲染)

import React, { Component } from "react";

export default class Timer extends Component {
  constructor(props) {
    super(props);

    try {
      this.state = JSON.parse(localStorage.getItem(this.props.localStorage));
    } catch (error) {}

    if (!this.state) {
      this.state = this.saveChanges({
        running: false,
        value: 0
      });
    }
  }

  componentWillMount() {
    if (this.state.running) {
      this.timer = setInterval(
        () => this.forceUpdate(),
        this.props.interval | 0
      );
    }
  }

  componentWillUnmount() {
    if (this.state.running) {
      clearInterval(this.timer);
    }
  }

  saveChanges(state) {
    console.log("saveChanges", this.props.localStorage, state);
    if (this.props.localStorage) {
      localStorage.setItem(this.props.localStorage, JSON.stringify(state));
    }
    return state;
  }

  start = () => {
    const now = Date.now();

    this.setState(({ running, value }) => {
      if (running) return null;

      this.timer = setInterval(
        () => this.forceUpdate(),
        this.props.interval | 0
      );

      return this.saveChanges({
        running: true,
        value: value - now
      });
    });
  };

  stop = () => {
    const now = Date.now();

    this.setState(({ running, value }) => {
      if (!running) return null;

      clearInterval(this.timer);
      return this.saveChanges({
        running: false,
        value: value + now
      });
    });
  };

  reset = () => {
    const now = Date.now();

    this.setState(({ running, value }) => {
      return this.saveChanges({
        running: false,
        value: 0
      });

      //just reset the timer to 0, don' stop it
      //return this.saveChanges({
      //  running,
      //  value: running? -now: 0
      //});
    });
  };

  render() {
    const {
      start, stop, reset,
      state: { running, value }
    } = this;

    const timestamp = running ? Date.now() + value : value;
    const h = Math.floor(timestamp / 3600000);
    const m = Math.floor(timestamp / 60000) % 60;
    const s = Math.floor(timestamp / 1000) % 60;
    const ms = timestamp % 1000;

    const _ = (nr, length = 2, padding = 0) =>
      String(nr).padStart(length, padding);

    return (
      <div className="container">
        <h2 className="text-center"> React Based Timer </h2>
        <div className="timer-container">
          <div className="current-timer">
            {_(h) + ":" + _(m) + ":" + _(s) + "." + _(ms, 3)}
          </div>
          <div className="timer-controls">
            <button className="btn btn-success" onClick={start}>
              Start Timer
            </button>

            <button className="btn btn-alert" onClick={stop}>
              Stop Timer
            </button>

            <button className="btn btn-danger" onClick={reset}>
              Reset!
            </button>
          </div>
        </div>
      </div>
    );
  }
}

签出此沙箱

Edit xpp1wrmmqp