JS-201-ReactFundamentals
  • Part 0: App Overview
  • Part 1: Intro to React
    • 1.0: Packages Setup
    • 1.1: Project Setup
    • 1.2: React Router Dom
  • Part 2: JavaScript Concepts
    • 2.0: ES6 Overview
    • 2.1: classes
    • 2.2: constructors
    • 2.3: extends
    • 2.4: super
    • 2.5: interpolation
    • 2.6: map
    • 2.7: filter
  • Part 3: Functional Components
    • 3.0: Functional Components Overview
    • 3.1: Calling Functional Components
    • 3.2: Single Element Rule
    • 3.3: Arrow Functions
    • 3.4: Challenge
    • 3.4: Solution
    • 3.5: Challenge 2
    • 3.5: Solution 2
  • Part 4: JSX Challenge
    • 4.1: JSX Overview
    • 4.1: Challenge Answer
    • 4.2: className
  • Part 5: Class Concepts
    • 5.1: State
    • 5.2: setState
    • 5.3: Class Components Challenge
    • 5.4: Class Components Challenge Answer
  • Part 6: Props Starter
    • 6.0: Props Overview
    • 6.1: Props Demo and Challenge 1
    • 6.2: Props Answer 2
    • 6.3: Props Passing Functions and Challenge 2
    • 6.4: Props Answer 2
    • 6.5: External Props and Mapping Components
    • 6.6: PropTypes
  • Part 7: Lifecycle Methods
    • 7.0: Lifecycle Overview
    • 7.1: Lifecycle Methods
    • 7.2: Mounting Methods
    • 7.3: Update Methods
    • 7.4: Unmount Methods
  • Part 8: Apps
    • 1.0 - Small Timer Apps
      • 1.1 - Simple Timer
      • 1.2 - Clock App
      • 1.3 - Stop Watch App
      • 1.4 - Challenge
    • 2.0 - Concept List
      • 2.1 - Concept Data
      • 2.2 - Concept App Component
      • 2.3 - Concept Component
      • 2.4 - Concept List Component
    • 3.0 - NYT
      • 3.1 - NytApp Component
      • 3.2 - Nyt Results
    • 4.0 - The Friend List App
      • 4.1 - Friend List App Component
      • 4.2 - Friend Component
    • 5.0 - Movie Search Application
      • 5.1 - Form Component
      • 5.2 - Form Results Component
      • 5.3 - Styled Components
    • 6.0 - YouTube Api
      • 6.1 - Video Component
      • 6.2 - Video Component
      • 6.3 - Video Component
    • 7.0 - Github Api Application
      • 7.1 - The Users
      • 7.2 - Github API Component
      • 7.3 - Github API Card
      • 7.4 - Github API Card Form
      • 7.5 - Github API Card List
      • 7.6 - Github API Search
      • 7.7 - Github API Challenge
    • 8.0 - Bitcoin Api Application
      • 8.1 - Bitcoin API Setup
      • 8.2 - Bitcoin API Fetch
      • 8.3 - Bitcoin API Line Chart
      • 8.4 - Bitcoin API Fetching Data
      • 8.5 - Bitcoin API Info Box
      • 8.6 - Bitcoin API Completed Code
    • 9.0 - Google Maps Api Challenge
    • 10.0 - Sound Cloud App Challenge
    • 11.0 - VR App Challenge
    • 12.0 - React Native Intro
  • Part 9: Project
  • Part 10: Notes
    • 10.1 - Resources
    • 10.2 - Troubleshooting
Powered by GitBook
On this page
  • Component Starter
  • State Set up
  • Time Check
  • componentDidMount
  • Check the clock
  1. Part 8: Apps
  2. 1.0 - Small Timer Apps

1.2 - Clock App

This next time app we're going to make is going to tell us what time it is! So a little bit more complex than a simple timer, but still utilizing many of the same lifestyle methods.

Component Starter

To start we need to create a ClockApp.js file inside of our timer-apps folder. Your timer-apps should look like the following.

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

Let's go ahead and get our ClockApp file started with the following code:

import React, { Component } from 'react';

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

Next, to get this to display, we need to change our parent component, TimePiecesApp to no longer have CloakApp commented out, so go ahead and make sure that your TimePiecesApp file looks like this.

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;

Now you should see your Clock App h1, to know you've correctly gotten your component to display!

State Set up

For this app, our goal is to display the current time. To do this, we need to set up our state in this component to be the current time, and then have that time be displayed in our render.

So, the first thing we can do is set up our state to have our current time. As usual, to initiate state, we can do this inside of our constructor. Remember to include super(props) inside of your constructor as well. Type the following code at the top of your ClockApp class.

constructor(props) {
    super(props);
    var date = this.getTimeString();
    this.state = {
      time: date
    }
  }
getTimeString() {
    const date = new Date(Date.now()).toLocaleTimeString();
    return date;
  }

So now our state should reflect the current time. But we haven't rendered this to the screen yet, so let's go ahead and add it to our render. See if you can figured out how to add it without looking at the below code. Remember to use this, when needed.

Did you add it successfully? Either way, check out the below code for our render() function, to compare to yours.

render() {
    return (
      <div>
        <h1 className="section-title">React Clock</h1>
        <hr className="explanation" />
        <p>{this.state.time}</p>
      </div>
    );
  }

Time Check

Now that we have it rendering the time, do you think this will update to the new time? If you're unsure, watch and see what happens, are the seconds moving?

Why isn't it updating with the time? Think back to our timer app, and remember what we had to do to get the seconds to update every single second. We'll need to do something similar here, to get our clock to update every single second. Just like the simple timer app, we'll need to use componentDidMount() to set our interval, and componentWillUnmount() to stop the interval when we navigate away or the component is no longer needed.

componentDidMount

In our componentDidMount we need some way to update our time part of our state every second with the current updated time. In the below code, we are ensuring that this happens every one second.

componentDidMount() {
    const _this = this;
    this.timer = setInterval(function () {
      var date = _this.getTimeString();
      _this.setState({
        time: date
      })
    }, 1000)
}

Notice the first line of ComponentDidMount(), why are we creating a new const _this? Try commenting out the const _this = this and using this instead of _this in the rest of this block of code. It throws an error, and says that this.getTimeString() is not a function.

Why does it do this? This is due to scoping in JavaScript. Where we set _this = this, this is in the global scope, but inside of the function(), we now have a local scope, so if we try to use regular this inside of the function, it is pointing to the local scope of the function, which is not what we want.

Check the clock

Now that we have our setInterval with our date, we are correctly able to see a clock that updates!! Now, just like our simple timer app, we need to make sure that when we leave the page, whent the component unmounts, that the setInterval is not still going. So again, we're going to clearInterval in componentWillUnmount.

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

And that takes care of our clock app! Hopefully you have a better understanding of some of the lifestyle methods in react, and some more information on this scoping JS. Check your final code against the code below, to ensure that it's all correct. Next up is a stop watch app!

import React, { Component } from 'react';

export default class ClockApp extends Component {
  constructor(props) {
    super(props);
    var date = this.getTimeString();
    this.state = {
      time: date
    }
  }
  getTimeString() {
    const date = new Date(Date.now()).toLocaleTimeString();
    return date;
  }
  componentDidMount() {
    const _this = this;
    this.timer = setInterval(function () {
      var date = _this.getTimeString();
      _this.setState({
        time: date
      })
    }, 1000)
  }
  componentWillUnmount() {
    clearInterval(this.timer);
  }
  render() {
    return (
      <div>
        <h1 className="section-title">React Clock</h1>
        <hr className="explanation" />
        <p>{this.state.time}</p>
      </div>
    );
  }
}
Previous1.1 - Simple TimerNext1.3 - Stop Watch App

Last updated 7 years ago

We also need to define our getTimeString(), so underneath our constructor we're going to create a method to get the current time. We can use build in javascript Date, see for more info on Date. Put our getTimeString() method underneath the constructor.

So, to prevent this issue, we set const _this = this first, so that we are then able to use the correctly scoped this when we need to. See for another explanation that uses examples in vanilla JS and jQuery, or for an extremely in depth explanation.

here
here
here
Stopwatch App Setup