# 1.1 - Simple Timer

Create a file called `TimerApp.js` inside our timer-apps folder. Ensure, like always, that this is capitalized, as it is a react component.

```
    └── src
        └── assets
        └── components
                └── apps
                    └── timer-apps
                        └── TimePiecesApp.js
                        └── TimerApp.js
```

## Adjust Errors

Next, in our TimePiecesApp component, let's go ahead and comment out the references to the other apps we've not yet created, so that we will no longer get errors. Ensure that your `TimePiecesApp.js` looks like this.

```javascript
import React from 'react';
import TimerApp from './TimerApp';
// import ClockApp from './ClockApp';
// import StopWatchApp from './StopWatchApp'


const TimePiecesApp = () => {
    return (
        <div className="main">
            <div className="mainDiv">
                <TimerApp />
                {/* <hr />
                <ClockApp />
                <hr />
                <StopWatchApp /> */}
            </div>
        </div>
    )
}

export default TimePiecesApp;
```

Also, to remove the new error, we need to make TimerApp a React component with an export, so that React can understand what is happening.

## Starter Code

Type the following code into `TimerApp.js`. Reminder on the import: by importing Component inside curly braces, we can just extend Component instead of typing React.Component. Importing this way is common when you want to use specific exports of the package:

```javascript
import React, { Component } from 'react';

export default class TimerApp extends Component {
  render() {
    return (
      <div>
          <h1 className="section-title">React Timer</h1> 
      </div>
    );
  }
}
```

Now, you should no longer see any error, and instead see react timer displayed on your screen!

## Timer State

Next, we want to think about how we can implement a timer. The goal of this app is to perform as a simple timer. When we go into this timer page, we want it to start ticking every second, and diplay the time elapsed. This is not going to calculate anything complex, simply display the time elapsed, in seconds, and it will update every second.

The first thing we need to do is to set a state for this time that we want to display and update when it changes. We can set our initial state for this component in the constructor. As always in our constructor, we need to take in props, use `super(props)`, and then we can set our state.

Go ahead and type out the following code for your constructor. We're starting our secondsElapsed off at 0, so that the timer starts at 0 when we first enter the page.

```javascript
  constructor(props) {
    super(props);
    this.state = {secondsElapsed: 0};
  }
```

## Timer Value

Now that we have our initial state set to 0, we want to display the seconds elapsed in our render method. We can just call it from the state. Remember that we need to use this to access the state. Add a div in with the secondsElapsed from the state being displayed.

```javascript
 render() {
    return (
      <div>
          <h1 className="section-title">React Timer</h1> 
          <div>Seconds Elapsed: {this.state.secondsElapsed}</div>
      </div>
    );
  }
```

At this point, we now have our state set up, and the state displayed, however our secondsElapsed is currently always 0, not really a great timer yet. How can we get it so that it changes every second, and also get our component to update the display?

## Timer Method

The second part is easy, React will re-render on state changes, so we don't have to explicitly tell it to re-render when our state changes, we just need to focus on the first part, update the state so that every second it increases by 1. So every 1 second or (1000 ms) we increment our secondsElapsed by 1, or simply add 1 to it. So, we'll need two parts to this:

1. Create a method to add 1 to secondsElapsed
2. Create something that will call the above method every 1 second or 1000 ms

For part 1, we can just take in the previous state, which is really only the secondsElapsed, and add one to it. Add the following code to your class, underneath your constructor. Remember, that state is an object, so when we use previous state here, we are getting the secondsElapsed specifically and adding one to it.

```javascript
  tick() {
    this.setState((prevState) => ({
      secondsElapsed: prevState.secondsElapsed + 1
    }));
  }
```

Now that we have this method, we need some way to call it every single second. Since right now it just exists, and isn't being called by anything, so our timer is still reading 0 forever. We really want this to start counting after everything is good to go on the page, so we can setup a way to call this method every second within `componentDidMount()`. We can use `setInterval()`, a JavaScript method that repeats a given function at every given time-interval. Since we want our `tick()` method to happen every 1000ms, we can set that up. Remember that we need to use `this.tick()` to correctly be able to call our method. Type the following underneath our tick() method:

```javascript
componentDidMount() {
    this.interval = setInterval(() => this.tick(), 1000);
    console.log(this.interval);
  }
```

Now you should be able to see your timer counting correctly!! Hooray!

## Error

There is one last thing to take care of, first, go to your timer app, and then navigate away from it. Notice that react throws you an error. You should see something like this, "Warning: Can only update a mounted or mounting component. This usually means you called setState, replaceState, or forceUpdate on an unmounted component. This is a no-op.

Please check the code for the TimerApp component."

To fix this, we need to make sure that our interval is stopped when we no longer want to view this component, or in `componentWillUnmount()`. By stopping the interval in this lifecycle method, when we navigate away from this page, it will no longer continue to try and update the component. Write the following code below your `componentDidMount()`

```javascript
  componentWillUnmount() {
    clearInterval(this.interval);
        console.log(this.interval);

  }
```

Now, try navigating to another part of your app, for example home, and check to make sure that the error is no longer there. Awesome, we've finished our very simple timer app. The complete code is below if you need it for reference!

## The full code

```javascript
//Source: https://facebook.github.io/react/
import React, { Component } from 'react';

export default class TimerApp extends Component {
  constructor(props) {
    super(props);
    this.state = {secondsElapsed: 0};
  }

  tick() {
    this.setState((prevState) => ({
      secondsElapsed: prevState.secondsElapsed + 1
    }));
  }

  componentDidMount() {
    this.interval = setInterval(() => this.tick(), 1000);
    console.log(this.interval);
  }

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

  render() {
    return (
      <div>
          <h1 className="section-title">React Timer</h1> 
          <div>Seconds Elapsed: {this.state.secondsElapsed}</div>
      </div>
    );
  }
}
```

[Clock App Setup](/javascript-301-reactfundamentals/part-8-apps/1.0-small-timer-apps/1.2-clock-app.md)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://eleven-fifty-academy.gitbook.io/javascript-301-reactfundamentals/part-8-apps/1.0-small-timer-apps/1.1-simple-timer.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
