首页 > 解决方案 > REACT / JAVASCRIPT 中一些组件的主计数器

问题描述

我必须对作为板上元素的卡进行计数器,问题是这个计时器是关于一个组件的,当我关闭卡对话框时,计数器不起作用,我的想法是继续计数,我可以打开另一张卡并打开计时器。仅当我单击停止并保存时才停止计时器。谢谢。

Board --> BoardCardDialog --> 定时器

Board.js

...

state = {
  timeCards: []
}

cardTimer= (time, cardID) => {
    var card = {
      id: cardID,
      hours: time.h,
      minutes: time.m,
      seconds: time.s
    };
    
    let coincidence= this.state.timeCards.filter(i => i.id === cardID);
    if (coincidence.length === 0) {
      let timeCards = this.state.timeCards;
      timeCards.push(card);
      this.setState({
        timeCards
      });
    } else {
      this.setState({
        timeCards: this.state.timeCards.map(c => {
          if (c.id === cardID) {
            return {
              id: cardID,
              hours: time.h,
              minutes: time.m,
              seconds: time.s
            };
          }
          return c;
        })
      });
    }
  };

<BoardCardDialog
 ...
 cardTimer={this.cardTimer}
 />

...

BoardCardDialog.js

...

<div className="flex flex-col sm:flex-row">
              <div className="flex-1">
                <div className="flex items-center mt-16 mb-12">
                  <Icon className="text-20 mr-8" color="inherit">
                    access_time
                  </Icon>
                  <Typography className="font-600 text-16">
                    Add time
                  </Typography>
                </div>
              </div>
            </div>
            <Timer
             ...
              cardTimer={cardTimer}
              cardID={card.id}
            />
...

计时器.js

...

class Timer extends Component {

  constructor() {
    super();
    this.state = {
      time: {
        h: 0,
        m: 0,
        s: 0
      },
      seconds: 0,
      running: false,
      timeCards: []
    }

    this.timer = 0;
    this.startTimer = this.startTimer.bind(this);
    this.countDown = this.countDown.bind(this);
  }

  secondsToTime(secs) {
    let hours = Math.floor(secs / (60 * 60));

    let divisor_for_minutes = secs % (60 * 60);
    let minutes = Math.floor(divisor_for_minutes / 60);

    let divisor_for_seconds = divisor_for_minutes % 60;
    let seconds = Math.ceil(divisor_for_seconds);

    let obj = {
      h: hours,
      m: minutes,
      s: seconds
    };
    this.props.cardTimer(obj, this.props.cardID)
    return obj;
  }

  componentDidMount() {
    let timeLeftVar = this.secondsToTime(this.state.seconds);
    this.setState({ time: timeLeftVar });
  }

  startTimer() {
    this.setState({ running: true });
    this.timer = setInterval(this.countDown, 1000);
  }

  countDown() {
    // Remove one second, set state so a re-render happens.
    let seconds = this.state.seconds + 1;
    this.setState({
      time: this.secondsToTime(seconds),
      seconds: seconds
    });
  }

  render() {
    return (
      <div>
        <h4 className="mb-12">
          {this.state.time.h}h {this.state.time.m}m {this.state.time.s}s
        </h4>
        {this.state.running ? (
          <React.Fragment>
            <Button
              variant="contained"
              color="secondary"
              onClick={() => {
                clearInterval(this.timer);
                this.setState({ running: false });
              }}
            >
              <Icon>stop</Icon>
            </Button>
          </React.Fragment>
        ) : (
          <React.Fragment>
            <Button
              variant="contained"
              color="secondary"
              onClick={this.startTimer}
            >
              <Icon>play_arrow</Icon>
            </Button>
            {this.state.seconds > 0 && (
              <Button
                variant="contained"
                color="secondary"
                onClick={() => {
                  this.props.saveTimer(this.state);
                  this.setState({
                    time: {
                      h: 0,
                      m: 0,
                      s: 0
                    },
                    seconds: 0,
                    running: false
                  });
                }}
              >
                <Icon>save</Icon>
              </Button>
            )}
          </React.Fragment>
        )}
      </div>
    );
  }
}

export default Timer;

标签: javascriptreactjsreact-reduxcounter

解决方案


推荐阅读