-1

I'm trying to implement a ticking timer using moment.js in my presenational React component. As a first step, I wanted to just call a function every second but instead of getting the text the function should return, I'm getting an int value.

Any idea how I should implement this?

Here's my component:

import React, { PropTypes } from 'react';
import moment from 'moment';

const tickingTimer = () => {

   return "00:02:48";
}

const MyComponent = () => {

   return(
      <div>
         <div>{setInterval(tickingTimer(), 1000)}</div>
      </div>
   );
}

export default MyComponent;

When React renders the page, instead of seeing 00:02:48, I'm getting int values that go up 3 times e.g. 20, 21, 22

How do call a function that will return a value every second in my presentational component?

Sam
  • 19,814
  • 35
  • 141
  • 272

1 Answers1

1

The reason for it is that setInterval returns a timerId which you can use later to clear the interval.

You need to save the returned value of function in state

import React, { PropTypes } from 'react';
import moment from 'moment';

const tickingTimer = () => {

   return "00:02:48";
}

const MyComponent class extends React.Component {
   state = { 
      timer: ''
   }
   componentDidMount(){
       setInterval(tickingTimer, 1000)
   }

   tickingTimer = () => {

     this.setState({timer:"00:02:48"});
    }
   return(
      <div>
         <div>{this.state.timer}</div>
      </div>
   );
}

export default MyComponent;
Shubham Khatri
  • 211,155
  • 45
  • 305
  • 318
  • Thank you. The only thing I need to figure out is implementing this in a presentational component. I don't think I can use `componentDidMount()` in a presenational component. – Sam Jan 02 '18 at 06:14
  • @Sam It makes zero sense to have a presentational component if you're going to have a timer. A timer by definition has internal state and presentational components shouldn't/can't have internal state. – Andrew Li Jan 02 '18 at 06:19
  • No you can't, either you need to paas it down from the parent – Shubham Khatri Jan 02 '18 at 06:19
  • In this particular case, my time is going to show me the hours, minutes and seconds passed since a set time which I store in my `Redux` store. That value is not changing. `moment` should simply be displaying the elapsed time since that set date/time. In this case, the state of my value is not changing. This is why I'm using `moment` and was going with a presenational component. – Sam Jan 02 '18 at 06:25
  • why do you need a setInterval then – Shubham Khatri Jan 02 '18 at 06:26
  • Here's why: say the value I pass to my presentational component is `3:45:10 PM`. I want to display a ticking timer that shows me how many hours, minutes and seconds since `3:45:10` – Sam Jan 02 '18 at 06:27
  • Maybe timer is the wrong word to use. It's not counting down. It should be counting up. Keeps calculating how much elapsed time since `3:45:10 PM` – Sam Jan 02 '18 at 06:28
  • You need a setInterval, but you can't get the returned value of the function executed in setInterval, the way to go forward is to extend the React.Component class and store it in state – Shubham Khatri Jan 02 '18 at 06:30
  • I can use a smart component. It's not a deal breaker. Just wanted to keep it simple by using a presenational component. Anyway, thanks for your help. – Sam Jan 02 '18 at 06:32
  • @ShubhamKhatri I implemented your code exactly the way you have it here. It displays the initial value but I don't think `setInterval` is working. The value never changes. Any idea why that might be? – Sam Jan 02 '18 at 06:50
  • Thats because in the implementation of `tickingTimer` you need to update the state with the correct value instead of a default string – Shubham Khatri Jan 02 '18 at 07:09