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
  • Adjust Errors
  • Starter Code
  • Timer State
  • Timer Value
  • Timer Method
  • Error
  • The full code
  1. Part 8: Apps
  2. 1.0 - Small Timer Apps

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.

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:

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.

  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.

 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.

  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:

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()

  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

//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>
    );
  }
}
Previous1.0 - Small Timer AppsNext1.2 - Clock App

Last updated 7 years ago

Clock App Setup