Render a timer component onClick

Kevin T.

I have a Timer component in a returned from a TimerContainer

const Timer = ({ time = 0 }) => (
 <div className={styles.timer}>{formatTime(time)}</div>
);

Timer.propTypes = {
  time: PropTypes.number
};

class TimerContainer extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      secondsElapsed: 0
    };
  }

  componentDidMount() {
    this.interval = setInterval(this.tick.bind(this), 1000);
  }

  componentWillUnmount() {
    clearInterval(this.interval);
  }

  tick() {
    this.setState({
      secondsElapsed: this.state.secondsElapsed + 1
    });
  }

  render() {
    return <Timer time={this.state.secondsElapsed} />;
  }
}

How do I get it to only start when I click on another Button component? In my main component I have two functions for the Buttons

handleEasyCards() {
    this.setState(prevState => ({ currentCards: this.state.easyCards }));
  }

  handleHardCards() {
    this.setState({ currentCards: this.state.hardCards });
  }

  render() {
    return (
      <div style={boardContainer}>
        <div style={buttonContainer}>
          <Button
            difficulty={this.state.easyButton}
            onClick={this.handleEasyCards}
          />
          <Button
            difficulty={this.state.hardButton}
            onClick={this.handleHardCards}
          />
        </div>
        <Cards
          cardTypes={this.state.currentCards}
          removeMatches={this.removeMatches}
        />
      </div>
    );
  }
}

I think I need to pass a callback to the Button component and call it in the handleHardCards and handleEasyCards. I don't think this is a conditional render because the Timer will start with either Button clicked.

Tomasz Mularczyk

You could have another variable in the state:

  constructor(props) {
    super(props);
    this.state = {
      secondsElapsed: 0,
      isCountingTime: false,
    };
  }

Then change that variable when an event happen:

handleEasyCards() {
  this.setState(prevState => ({ 
    currentCards: this.state.easyCards,
    isCountingTime: true,
  }));
}

handleHardCards() {
  this.setState({ 
    currentCards: this.state.hardCards,
    isCountingTime: true,
  });
}

Until now Timer has not been mounted so have not started counting. But with isCountingTime set to true it will render and start counting:

<div style={boardContainer}>
  {this.state.isCountingTime && <Timer />}
  ...
</div>

The good part is that you can "start" and "reset" Timer whenever you want just by changing isCountingTime variable to true. The bad part is that nothing is rendered (no default values) when is set to false.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related