Build Your First App with React's Context API

Build Your First App with React's Context API

Build Your First App with React's Context API. One of React's latest features is the Context API. Up until now, Context within React has been somewhat experimental, but still used in quite a few popular libraries, like Redux and React Router.

Build Your First App with React's Context API. One of React's latest features is the Context API. Up until now, Context within React has been somewhat experimental, but still used in quite a few popular libraries, like Redux and React Router.

One of React’s latest features is the Context API. Up until now, Context within React has been somewhat experimental, but still used in quite a few popular libraries, like Redux and React Router. There are plenty of ways to avoid using Context, but sometimes it can be really useful.

One really good use case for Context is keeping track of authentication. In fact, React’s official documentation for the Context API mentions it can be used for authentication.

Context is designed to share data that can be considered “global” for a tree of React components, such as the current authenticated user, theme, or preferred language.### Table of Contents

The examples in their documentation are helpful, but they don’t actually include an example of sharing the authenticated user. I’ll show you here how one way to use the new Context API to simply keep track of whether a user is authenticated, and some basic profile information.

React Context in a Nutshell

Before going too far down the rabbit hole, let me give you a quick introduction into the Context API. As of React version 16, React ships with a function called createContext that takes a single value parameter. Calling createContext gives you both a Provider and Consumer component.

You can render the Provider component anywhere in your app - in multiple places if you like. If there is a Consumer anywhere inside the Provider (even deeply nested somewhere), it will have access to that value parameter in the form of a render function as a child. Each Provider can also override the value. For example:

import { createContext } from 'react';

const { Provider, Consumer } = createContext('default value');

export default () =>
  <main>
    <Provider>
      <Consumer>{value => <span>{value}</span>}</Consumer>
    </Provider>
    <Provider value="overridden value">
      <div>
        <Consumer>{value => <span>{value}</span>}</Consumer>
      </div>
    </Provider>
  </main>
);

Will render the following:

<main>
  <span>default value</span>
  </div>
    <span>overridden value</span>
  </div>
</main>

Because Provider is just a component, you can easily create a wrapper component that passes its state into the value prop of the Provider. Then you will have access to that component’s state anywhere in the app via the Consumer. In this tutorial, I’ll show you how to use one component to keep track of auth state changes and pass that information down via the Context API.

Build a Simple React App

The quickest way to get started with React in my experience is using the official Create React App CLI. It bootstraps an app for you giving you some decent defaults. To use it, install it globally with NPM, then run it with the name of your app as a parameter. This will create a new folder with everything you need to get started, and will even install the dependencies for you. You can then run the app using yarn start.

npm install --global [email protected] [email protected]
create-react-app react-context
cd react-context
yarn start

You should now be able to see your app running by visiting [http://localhost:3000](http://localhost:3000 "http://localhost:3000") with your browser.

For this tutorial, I’ll show you how you can take advantage of the new Context API to cut down some of the boilerplate that is often paired with authentication. Before getting started with Context, you’ll need to set up authentication in order to tie it in.

Create an Okta Application

One simple way to add authentication to your project is with Okta. Okta is a cloud service that allows developers to create, edit, and securely store user accounts and user account data, and connect them with one or multiple applications. Our API enables you to:

If you don’t already have one, sign up for a forever-free developer account. Log in to your developer console, navigate to Applications, then click Add Application. Select Single-Page App, then click Next.

Since Create React App runs on port 3000 by default, you should add that as a Base URI and Login Redirect URI. Your settings should look like the following:

Click Done to save your app, then copy your Client ID and paste it as a variable into a file called .env.local in the root of your project. This will allow you to access the file in your code without needing to store credentials in source control. You’ll also need to add your organization URL (without the -admin suffix). Environment variables (other than NODE_ENV) need to start with REACT_APP_ in order for Create React App to read them, so the file should end up looking like this:

.env.local

REACT_APP_OKTA_CLIENT_ID={yourClientId}
REACT_APP_OKTA_ORG_URL=https://{yourOktaDomain}

The easiest way to add authentication with Okta is to use Okta’s React SDK. You’ll also need to add routes, which can be done using React Router. I’ll also have you start adding icons to the app (for now as an avatar icon to show you’re logged in).

yarn add @okta/[email protected] [email protected]

For routes to work properly using React Router, you need to wrap your whole application in a router (for the web, you need to use BrowserRouter). Similarly, to allow access to authentication anywhere in the app, you need to wrap the app in a Security component provided by Okta. Okta also needs access to the router, so the Security component should be nested inside the router. You should modify your src/index.js file to look like the following:

src/index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import { Security } from '@okta/okta-react';

import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';

const oktaConfig = {
  issuer: `${process.env.REACT_APP_OKTA_ORG_URL}/oauth2/default`,
  redirect_uri: `${window.location.origin}/implicit/callback`,
  client_id: process.env.REACT_APP_OKTA_CLIENT_ID,
};

ReactDOM.render(
  <BrowserRouter>
    <Security {...oktaConfig}>
      <App />
    </Security>
  </BrowserRouter>,
  document.getElementById('root'),
);

registerServiceWorker();

Now in src/App.js you can use Routes that tell the app to only render a certain component if the current URL matches the given path. You can also use Links to create a link to that route (or page) and properly modify the browser’s history to work in a single-page app.

Go ahead and create a nav tag with links to the Home page (/) and a Profile page (/profile). Also, create a main tag containing your routes. For now just stub in some inline components that render the name of the page.

By using Okta’s SecureRoute you will find that whenever you try to go to that page you will need to be logged in. If you’re not currently logged in, you’ll be redirected to /implicit/callback to log in. In order for that route to actually log you in, you also need to create a route that renders Okta’s ImplicitCallback component.

src/App.js

--- a/src/App.js
+++ b/src/App.js
@@ -1,4 +1,7 @@
 import React, { Component } from 'react';
+import { Link, Route } from 'react-router-dom';
+import { SecureRoute, ImplicitCallback } from '@okta/okta-react';
+
 import logo from './logo.svg';
 import './App.css';

@@ -9,10 +12,16 @@ class App extends Component {
         <header className="App-header">
           <img src={logo} className="App-logo" alt="logo" />
           <h1 className="App-title">Welcome to React</h1>
+          <nav className="App-nav">
+            <Link to="/">Home</Link>
+            <Link to="/profile">Profile</Link>
+          </nav>
         </header>
-        <p className="App-intro">
-          To get started, edit <code>src/App.js</code> and save to reload.
-        </p>
+        <main className="App-intro">
+          <Route exact path="/" component={() => 'Home Page'} />
+          <SecureRoute exact path="/profile" component={() => 'Profile page'} />
+          <Route path="/implicit/callback" component={ImplicitCallback} />
+        </main>
       </div>
     );
   }

Note: You can apply a diff in git by copying it to a file and using the git apply command. If you’re following along this avoids having to write the file out manually. For example, if you save the above as a file named app.diff, then from your project folder, you could type git apply app.diff and it should apply those changes.

To make this look a little nicer, add a bit of CSS to let the header expand to the content, give the main part of the app some padding, and make the nav links a bit more readable.

src/App.css

--- a/src/App.css
+++ b/src/App.css
@@ -9,17 +9,35 @@

 .App-header {
   background-color: #222;
-  height: 150px;
+  min-height: 150px;
   padding: 20px;
   color: white;
 }

+.App-nav {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+.App-nav a {
+  color: white;
+  padding: 0 5px;
+  text-decoration: none;
+  cursor: pointer;
+}
+
+.App-nav a:hover {
+  text-decoration: underline;
+}
+
 .App-title {
   font-size: 1.5em;
 }

 .App-intro {
   font-size: large;
+  margin: 1em;
 }

You should now have a slightly modified version of the default page from Create React App that says “Home page”. You should also now be able to click on the Profile link and you will be prompted to log in to your account. Upon success, you’ll be taken to the profile page, that at the moment just says Profile page.

Note: You may need to restart the development server after adding the environment variables. You can do this by going to the terminal running the server and hitting ctrl-c, then re-running the yarn start command.

Add a User Greeting with React Context

Using React’s new Context API, you can create a component that you will use to wrap your entire application, similar to the way BrowserRouter or Security works. Once that Provider is in place, you can access pieces of authentication anywhere in the application without a lot of boilerplate.

In this case, create a context using createContext. You’ll then check when the component is first mounted, and again whenever it updates, if the user is authenticated. If this is different from the current state, then it also checks for the user and saves that as well. The reason the state is only updated whenever the authentication is different from the previous state is that otherwise, the componentDidUpdate function would trigger another update, sending this component into an infinite render loop.

To keep this simple to use, the default export is the Context’s Consumer. The Provider component is exported separately and is wrapped with Okta’s withAuth to give it access to the auth prop.

Note: Checking authentication during componentDidUpdate is admittedly not the most efficient method. At the time of this writing, there is not a simple way to detect when the state of authorization changes, so this is a simple approach for demo purposes. This example might not work well for larger applications.

src/Auth.js

import React, { createContext, Component } from 'react';
import { withAuth } from '@okta/okta-react';

const AuthContext = createContext({
  user: null,
  isAuthenticated: null,
});

export default AuthContext.Consumer;

class AuthController extends Component {
  state = {
    user: null,
    isAuthenticated: null,
  }

  componentDidUpdate() {
    this.checkAuthentication();
  }

  componentDidMount() {
    this.checkAuthentication();
  }

  async checkAuthentication() {
    const isAuthenticated = await this.props.auth.isAuthenticated();
    if (isAuthenticated !== this.state.isAuthenticated) {
      const user = await this.props.auth.getUser();
      this.setState({ isAuthenticated, user });
    }
  }

  render() {
    return (
      <AuthContext.Provider value={this.state}>
        {this.props.children}
      </AuthContext.Provider>
    );
  }
}

export const AuthProvider = withAuth(AuthController);

The app’s main entry point now needs to be wrapped in the AuthProvider. It needs to be inside Security so that it can access the auth using withAuth.

src/index.js

--- a/src/index.js
+++ b/src/index.js
@@ -6,6 +6,7 @@ import { Security } from '@okta/okta-react';
 import './index.css';
 import App from './App';
 import registerServiceWorker from './registerServiceWorker';
+import { AuthProvider } from './Auth';

 const oktaConfig = {
   issuer: `${process.env.REACT_APP_OKTA_ORG_URL}/oauth2/default`,
@@ -16,7 +17,9 @@ const oktaConfig = {
 ReactDOM.render(
   <BrowserRouter>
     <Security {...oktaConfig}>
-      <App />
+      <AuthProvider>
+        <App />
+      </AuthProvider>
     </Security>
   </BrowserRouter>,
   document.getElementById('root')

Now that the Context Provider is set up and ready to go, you can start using the Consumer. For a quick example, try changing the homepage to greet the user when they’re logged in. If they aren’t logged in, keep the old message of Welcome to React.

React Contexts take a render function as its child element. The parameters passed in are going to be the state of the provider (the data passed into value). Because of this, to access the user, you need to pass in a function that expects an object containing the key user. If this is null then authentication is still loading. If it’s undefined then the user is not authenticated. Otherwise, it will contain the user’s basic profile information. Go ahead and ignore the loading state for now, and only greet the user once you have their information.

src/App.js

--- a/src/App.js
+++ b/src/App.js
@@ -5,13 +5,21 @@ import { SecureRoute, ImplicitCallback } from '@okta/okta-react';
 import logo from './logo.svg';
 import './App.css';

+import Auth from './Auth';
+
+const welcomeUser = ({ user }) => user
+  ? `Welcome, ${user.given_name || user.name}!`
+  : 'Welcome to React';
+
 class App extends Component {
   render() {
     return (
       <div className="App">
         <header className="App-header">
           <img src={logo} className="App-logo" alt="logo" />
-          <h1 className="App-title">Welcome to React</h1>
+          <h1 className="App-title">
+            <Auth>{welcomeUser}</Auth>
+          </h1>
           <nav className="App-nav">
             <Link to="/">Home</Link>
             <Link to="/profile">Profile</Link>

Create a Login/Logout Link

A pretty common scenario with authentication is having a button or link that you can click to log you in when you’re authenticated. You can use the same React Context to determine whether or not a user is logged in.

In order to properly log the user in or out when they click the link, you can wrap the component with withAuth to get access to the login and logout functions of auth.

This time, you don’t want the user to click either Login or Logout if you’re not sure what the state of authentication is yet. You could implement some sort of loading icon here, but for this demo just render nothing until you know whether or not the user is logged in.

src/LoginButton.js

import React from 'react';
import { withAuth } from '@okta/okta-react';

import Auth from './Auth';

export default withAuth(({ auth }) => (
  <Auth>
    {({ isAuthenticated }) => {
      if (isAuthenticated === null) return null;

      return (
        <a onClick={() => isAuthenticated ? auth.logout() : auth.login()}>
          {isAuthenticated ? 'Logout' : 'Login'}
        </a>
      );
    }}
  </Auth>
));

Now you can add the Login/Logout link to your list of nav items:

src/App.js

--- a/src/App.js
+++ b/src/App.js
@@ -6,6 +6,7 @@ import logo from './logo.svg';
 import './App.css';

 import Auth from './Auth';
+import LoginButton from './LoginButton';

 const welcomeUser = ({ user }) => user
   ? `Welcome, ${user.given_name || user.name}!`
@@ -23,6 +24,7 @@ class App extends Component {
           <nav className="App-nav">
             <Link to="/">Home</Link>
             <Link to="/profile">Profile</Link>
+            <LoginButton />
           </nav>
         </header>
         <main className="App-intro">

Create a Real Profile Page

From the user value in your Context, you can also now get access to the user’s basic profile information.

Semantically, a dl HTML tag is a “Description List” element. This is a good, basic way to display metadata. However, you’ll probably want to add a little bit of simple styling. This will make sure the text isn’t center-aligned, and make the term (the dt tag) bold. Create a new file Profile.css that you’ll import in your profile page.

src/Profile.css

dl {
  text-align: left;
}

dt {
  padding: 4px 0;
  font-weight: bold;
}

Lodash provides a suite of utilities to manipulate data. To keep things simple and automated, try using that to convert the name of a key to something more personable. The startCase function will convert a string like given_name to Given Name. To add Lodash as a dependency, run the following:

yarn add [email protected]

The updated_at key is actually just a number representing the number of seconds from 1970, so you can convert that to a human-readable string in JavaScript using new Date(updated_at * 1000).toString().

Putting all that together, you can create a functional component that takes a user prop, and wrap that in the Auth Context Consumer. This time, show a simple loading message if the user isn’t loaded yet. Technically, the user will be undefined if authentication finished and there is no user, but because this is in a SecureRoute, if there is no user then the page will redirect to the home page.

src/Profile.js

import React, { Fragment } from 'react';
import { startCase } from 'lodash';

import Auth from './Auth';
import './Profile.css';

const ProfilePage = ({ user }) => {
  if (!user) return 'Loading...';

  return (
    <dl>
      {Object.keys(user).sort().map(key => (
        <Fragment key={key}>
          <dt>{startCase(key)}</dt>
          <dd>{key === 'updated_at' ? new Date(user[key] * 1000).toString() : user[key]}</dd>
        </Fragment>
      ))}
    </dl>
  );
}

export default () => <Auth>{ProfilePage}</Auth>;

In your app’s routes, replace the mock profile page with a reference to the real one you just created:

--- a/src/App.js
+++ b/src/App.js
@@ -7,6 +7,7 @@ import './App.css';

 import Auth from './Auth';
 import LoginButton from './LoginButton';
+import ProfilePage from './Profile';

 const welcomeUser = ({ user }) => user
   ? `Welcome, ${user.given_name || user.name}!`
@@ -29,7 +30,7 @@ class App extends Component {
         </header>
         <main className="App-intro">
           <Route exact path="/" component={() => 'Home Page'} />
-          <SecureRoute exact path="/profile" component={() => 'Profile page'} />
+          <SecureRoute exact path="/profile" component={ProfilePage} />
           <Route path="/implicit/callback" component={ImplicitCallback} />
         </main>
       </div>

Now when you go to the profile page, you get some details about the logged in user.

Learn More

React Tutorial: Building and Securing Your First App

Simple User Authentication in React

React Router: Add the Power of Navigation

Learn React - React Crash Course 2019 - React Tutorial with Examples

React Hooks Tutorial for Beginners: Getting Started With React Hooks

Learn React.js for Beginners

React - The Complete Guide (incl Hooks, React Router, Redux)

Modern React with Redux [2019 Update]

React Native - The Practical Guide

MERN Stack Front To Back: Full Stack React, Redux & Node.js

Full-Stack Web Apps with Meteor and React

React Hooks

What the difference between REST API and RESTful API?

What the difference between REST API and RESTful API?

Representational state transfer (REST) is a style of software architecture. As described in a dissertation by Roy Fielding, REST is an "architectural style" that basically exploits the existing technology and protocols of the Web. RESTful is typically used to refer to web services implementing such an architecture.

The short answer is that REST stands for Representational State Transfer. It’s an architectural pattern for creating web services. A RESTful service is one that implements that pattern.

The long answer starts with “sort of” and “it depends” and continues with more complete definitions.

Defining REST

Let’s start by defining what REST is and is not. For some, REST means a server that exchanges JSON documents with a client over HTTP. Not only is that not a complete definition, but it’s also not always true. The REST specification doesn’t require HTTP or JSON. (The spec doesn’t mention JSON or XML at all.)

The Origins of REST

Roy Fielding introduced the REST architectural pattern in a dissertation he wrote in 2000. The paper defines a means for clients and servers to exchange application data. A key feature is that the client doesn’t need to know anything about the application in advance. The link is to chapter five of his paper. While the entire dissertation describes the hows and whys of REST, that chapter defines the architectural pattern.

Fielding doesn’t mandate specific requirements. Instead, he defines REST regarding constraints and architectural elements.

REST’s Architectural Constraints

Here is a summary of the constraints.

  • Client-server – REST applications have a server that manages application data and state. The server communicates with a client that handles the user interactions. A clear separation of concerns divides the two components. This means you can update and improve them in independent tracks.
  • Stateless – servers don’t maintain any client state. Clients manage their application state. Their requests to servers contain all the information required to process them.
  • Cacheable – servers must mark their responses as cacheable or not. So, infrastructures and clients can cache them when possible to improve performance. They can dispose of non-cacheable Information, so no client uses stale data.
  • Uniform interface – this constraint is REST’s most well known feature or rule, depending on who you ask. Fielding says “The central feature that distinguishes the REST architectural style from other network-based styles is its emphasis on a uniform interface between components.” REST services provide data as resources, with a consistent namespace. We’ll cover this in detail below.
  • Layered system – components in the system cannot “see” beyond their layer. So, you can easily add load-balancers and proxies to improve security or performance.

A RESTful service is more than a web server that exchanges JSON, or any other, documents. These constraints work together to create a very specific type of application.

Applying the Constraints

First, the client-server, layered systems and stateless constraints combine to form an application with solid boundaries and clear separations between concerns. Data moves from the server to the client upon request. The client displays or manipulates it. If the state changes, the client sends it back to the server for storage. Fielding specifically contrasts REST with architectures that use distributed objects to hide data from other components. In REST, the client and server share knowledge about data and state. The architecture doesn’t conceal data, it only hides implementations.

The cacheable and uniform state constraints go one step further. Application data is available to clients in a clear and consistent interface and cached when possible.

So, that’s the technical definition of REST. What does it look like in the real world?

RPC Over HTTP vs. RESTful

Often when someone says that a service “isn’t REST,” they’re looking at the URIs or how the service uses HTTP verbs. They’re referring to REST’s presentation of data as a uniform set of resources.

This distinction is sometimes framed as a difference between remote procedures calls (RPC) and REST. Imagine a web service for listing, adding, and removing, items from an e-commerce inventory.

In one version, there’s a single URL that we query with HTTP GETs or POSTs.  You interact with the service by POSTing a document, setting the contents to reflect what you want to do.

Add new items with a POST with a NewItem:

POST /inventory HTTP/1.1
 
{
    "NewItem": {
          "name": "new item",
          "price": "9.99",
          "id": "1001"
      }
}    

Query for items with a POST and an ItemRequest:

POST /inventory HTTP/1.1
 
{
    "ItemRequest": {
          "id": "1001"
      }
}

Some implementations accept a request for a new item with a get, too.

POST /inventory?id=1001 HTTP/1.1

We also change or delete items with a POST and an ItemDelete or ItemUpdate.

POST /inventory HTTP/1.1
 
{
    "ItemDelete": {
          "id": "1001"
      }
}

This isn’t REST. We’re not exchanging the state of resources. We’re calling a function with arguments that happen to be in a JSON document or URL arguments.

A RESTful service has a URI for each item in the inventory.

So, adding a new item would look like the example above.

POST /item HTTP/1.1
 
{
    "Item": {
          "name": "new item",
          "price": "9.99",
          "id": "1001"
      }
}    

But the similarities end there. Retrieving an item is always a GET:

GET /item/1001 HTTP/1.1   

Deleting is a DELETE:

DELETE /item/1001 HTTP/1.1  

Modifying an item is a PUT:

POST /inventory HTTP/1.1
 
{
    "Item": {
          "name": "new item",
          "price": "7.99",
          "id": "1001"
      }
}    

The difference is important. In REST, operations that use distinct HTTP actions. These verbs correspond directly to the activity on the data. GET, POST, PUT, DELETE and PATCH all have specific contracts. Most well-designed REST APIs also return specific HTTP codes, depending on the result of the request.

The critical point is that the URIs operate on the data, not on remote methods.

But there’s another reason why the resource model is essential.

REST vs RESTful and the Richardson Maturity Model

When you model your URIs after resources and use HTTP verbs you make your API predictable. Once developers know how you defined your resources, they can almost predict what the API looks like. Here again, the emphasis is on understanding the data, not the operations.

But even if you can’t make the API entirely predictable, you can document any REST service with hypertext. So, each item returned in the inventory app would contain links for deleting, modifying, or setting the inventory level of the resource. Fielding says that before a service is RESTful, it must provide hypertext media as part of the API.

Many sites don’t meet this requirement but are still called REST. Fact is, many sites break the rules in one way or another. So many that Leonard Richardson created a model breaks down REST into levels of compliance

We’ve already covered the source levels:

  • 0 – exporting an API over HTTP with methods called with arguments
  • 1 – Exporting resources instead of methods
  • 2 – Proper use of HTTP verbs
  • 3 – Exporting hypertext with objects that make all or part of the API discoverable.

Richardson’s model is his own, and it doesn’t map directly into Fielding’s spec. Since Fielding requires level three, he would say that most apps aren’t REST anyway.

The point is many services that we colloquially refer to as REST, technically aren’t.

REST vs RESTful: Does It Matter?

So, does the REST vs. RESTful comparison matter? Probably not. How well your architecture complies with an arbitrary standard isn’t as important with how well it suits your needs and can grow with your business.

The REST architectural pattern has many advantages. Fielding designed it for the web and, 18 years later, most of the constraints he had in mind are still with us. In 2000 we didn’t have Android or the iPhone. IE5 had 50% of the browser market share. It’s biggest rival was Firefox. But Fielding recognized what online applications needed and how web clients would evolve from HTML display engines into complete applications. The tools we use today have grown to suit REST, not the other way around.

Thank you for reading. Hope this tutorial will help you!

Why ReactJS is better for Web Application Development?

Why ReactJS is better for Web Application Development?

Web Application Development is the point of contact for a business in today's digital era. It is important to choose the right platform for Web Application Development to build a high end Web

Web Application Development is essential for a business in today’s digital era. Finding the right platform for Web Application Development is important for building an effective Web Application that can enhance the overall customer engagement. Here’s what makes ReactJS a better option for building your next Web Application.

React and APIs - Full Tutorial - Hacker News API Application

React and APIs - Full Tutorial - Hacker News API Application

Learn how to use APIs with React in this intermediate tutorial. We're going to be creating a small application in React that calls the Hacker News API. We'll be looking at React memo, Axios (to make API calls), styled components, and finally we will test our work using React Testing Library.

React and APIs - Full Tutorial - Hacker News API Application

Once we have done all this we will run our application through Lighthouse (a browser extension) that allows us to test for accessibility, performance and so much more. We will be making 500+ automated API calls in this application, and I want to show you how to use memo with React so that we can avoid making multiple network calls if we already have the data.

💻 Code: https://github.com/karlhadwen/newsreader

⭐️ Course Contents ⭐️
⌨️ (0:00:00) Introduction (what are we building?), tech stack talk
⌨️ (0:01:50) Using create-react-app as our base
⌨️ (0:03:30) Stripping out the files & content that we do not need
⌨️ (0:05:00) Refactoring to named exports
⌨️ (0:08:35) Modifying our .env file
⌨️ (0:09:15) Scaffolding our application
⌨️ (0:10:15) Looking at the Hacker News Api
⌨️ (0:11:50) Looking at all the news article Ids
⌨️ (0:12:58) Adding Axios using Yarn
⌨️ (0:13:00) Creating our hnApi.js service file
⌨️ (0:15:07) Adding the ability to get all story Ids from HN Api
⌨️ (0:17:14) Starting work on App.js
⌨️ (0:22:30) Adding useEffect to App.js to show all story Ids
⌨️ (0:30:00) Explaining how useEffect works
⌨️ (0:36:00) Creating our StoriesContainer.js container/component
⌨️ (0:37:50) Adding the ability to get stories from HN Api
⌨️ (0:39:50) Demonstrating the results that we receive from the HN Api
⌨️ (0:41:30) Creating our Story.js component file
⌨️ (0:43:15) Adding our Story component to the StoriesContainer component
⌨️ (0:44:10) Adding storyId as a prop to the Story.js component
⌨️ (0:46:40) Adding state to our Story.js component
⌨️ (0:47:10) Using useEffect to get a story in our Story.js component
⌨️ (0:47:40) Adding validation when getting stories
⌨️ (0:49:00) Dumping our stories onto the page
⌨️ (0:49:55) Building out the Story.js component with real data
⌨️ (0:53:20) Adding a selector for the story fields
⌨️ (0:56:00) Adding styled components
⌨️ (0:57:00) Building out our StoryStyles.js file using styled components
⌨️ (0:59:00) Adding a title to StoriesContainer.js
⌨️ (1:00:00) Adding a StoryWrapper to our Story.js component
⌨️ (1:01:50) More work on styling
⌨️ (1:02:30) Adding styling for StoryMeta
⌨️ (1:03:55) Adding styling for StoryMetaElements & styled component props
⌨️ (1:04:55) Adding our styled components to our Story.js component
⌨️ (1:11:30) Adding StoriesContainerStyles for more styling on the container
⌨️ (1:12:05) Looking at adding global styles (createGlobalStyle)
⌨️ (1:13:00) Adding our container styles to StoriesContainer.js
⌨️ (1:14:55) Brief look at the React profiler
⌨️ (1:16:00) Quick run through as to what we have built so far
⌨️ (1:18:10) Making our time display properly using mapTime.js
⌨️ (1:22:00) Adding InfiniteScroll to our application (custom hook)
⌨️ (1:22:40) Constants to be used by InfiniteScroll for per page items
⌨️ (1:39:05) Adding debounce functionality for scrolling
⌨️ (1:42:00) Adding a fixture folder with fixtures for tests
⌨️ (1:46:00) Testing! Lets test App.js
⌨️ (1:48:00) Adding react-testing-library to our application
⌨️ (1:59:00) Adding Jest coverage (good practise to do so)
⌨️ (2:02:00) Testing the StoriesContainer.js
⌨️ (2:03:40) Testing the Story.js component
⌨️ (2:10:00) Testing the HnApi.js file
⌨️ (2:22:18) Looking at our coverage and more testing!
⌨️ (2:22:53) Collecting coverage from the right places
⌨️ (2:25:43) Looking at React memo
⌨️ (2:27:33) Adding memo to Story.js to prevent additional Api calls
⌨️ (2:29:18) Overview of what we have achieved!
⌨️ (2:30:29) Running our application through Lighthouse!
⌨️ (2:33:00) Thanks for watching, I hope you learned a lot!