0

I've made a child component where I have a timer arrow function. I used the console to log the function with and without parentheses. When I log without, it tells me the function is undefined. When I log with parentheses, it tells me the function is not a function. How can I prevent this? Here's the code...

import React from 'react';

class AlertsBox extends React.Component {
  constructor(props){
    super(props);
    this.state = {
      deadline: this.props.deadline,
      activate: this.props.activate,
      eta: Date.parse(this.props.deadline) - Date.now(),
      hora: ""
    };

    this.timer = this.timer.bind(this);
  }


//This is the function!
  timer = () => {
    //Extract the data from the original string
    //Convert the UTC to locale time

    let seconds = Math.round((this.state.eta/1000) % 60);
    let minutes = Math.floor( (this.state.eta/1000/60) % 60 );
    let hours = Math.floor( (this.state.eta/(1000*60*60)) % 24 );
    let days = Math.floor( this.state.eta/(1000*60*60*24) );

    this.setState({
      hora: `${days >= 1? days + " days" : ""} ${hours >= 1? hours + " hrs" : ""} ${minutes} min ${seconds} sec`
    });
  }


  componentDidMount() {
    setInterval(function () {
      this.timer;
      console.log(this.timer);
    }, 1000);
  }

  render() {

    return (
      <section className="alerts">
        <h1 className="alertname">
          {this.props.type.toUpperCase()} // {this.props.sector}
        </h1>
        <figure className="alertreward">
          <img src={this.props.image} alt=""/>
          {this.props.reward ?
            <figcaption>
              {this.props.reward}
            </figcaption>
          : null}
          <figcaption>
            {this.props.credits + " Credits"}
          </figcaption>

        </figure>

        <figure className="alerttimer">
          <canvas>
          </canvas>
          <p>{this.state.thepercent}</p>
          <figcaption>

              {this.state.hora}

          </figcaption>
        </figure>
      </section>
    )
  }
}

export default AlertsBox;
Matiny
  • 179
  • 3
  • 13
  • 2
    `this` is not the component when `setInterval` calls the function you pass to it. – Quentin Jan 22 '18 at 16:14
  • 1
    ...using an arrow function for the `setInterval` callback would fix that. Also note that there's no point to using `.bind(this)` on an arrow function (e.g., as you do in your constructor). – T.J. Crowder Jan 22 '18 at 16:14
  • It shouldn't be an arrow function anyway. – Pointy Jan 22 '18 at 16:14
  • @Pointy: Why not? It's a viable alternative to using `bind`...? – T.J. Crowder Jan 22 '18 at 16:15
  • @T.J.Crowder I meant the `timer()` function - it won't have `this` bound when it's called, yet it uses `this` on every line of code. (Unless I'm forgetting something about this hipster `class` thing.) – Pointy Jan 22 '18 at 16:16
  • Thanks, I missed the non-arrow setInterval function. – Matiny Jan 22 '18 at 16:18
  • @Pointy: The code above is using [class public instance fields](https://github.com/tc39/proposal-class-fields) (Stage 3). (If it weren't, that `timer = () => { ... };` would be a syntax error in a `class` body.) It's effectively identical to putting `this.timer = () => { ... };` in the constructor. – T.J. Crowder Jan 22 '18 at 16:27
  • 1
    ah OK, thanks. That makes sense. – Pointy Jan 22 '18 at 16:28

0 Answers0