Morning:
Afternoon:
<Router />
history
Deploying an app like Thing List is fairly simple, as it runs entirely on the client side (the browser). create-react-app makes it even easier.
create-react-app includes detailed instructions for deploying with GitHub Pages in the README.
Start by running the included build script.
yarn build
or
npm run build
This builds the browser-ready version of our app in a build
directory. (There are several aspects of our src
directory that make it less than ideal for production use. For example, recall that our app is written using JSX, which browsers don’t understand.)
It also prints out these instructions:
The project was built assuming it is hosted at the server root. To override this, specify the homepage in your package.json. For example, add this to build it for GitHub Pages: "homepage" : "http://myname.github.io/myapp",
To host the app on GitHub Pages (learn more about GitHub Pages), add the line to package.json
, just like it says, substituting your GitHub user name and repository name. In my case:
"name": "thing-list",
"version": "0.1.0",
"homepage": "http://xtbc17s1.github.io/thing-list",
Now run yarn build
again.
yarn build
This time, the output will include some more specific instructions.
The build folder is ready to be deployed. To publish it at http://xtbc17s1.github.io/thing-list, run: yarn add --dev gh-pages Add the following script in your package.json. // ... "scripts": { // ... "predeploy": "npm run build", "deploy": "gh-pages -d build" } Then run: yarn run deploy
Cool! Let’s add the gh-pages
package.
yarn add --dev gh-pages
or
npm install --save-dev gh-pages
Now let’s add those two scripts to package.json
.
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject",
"predeploy": "npm run build",
"deploy": "gh-pages -d build"
}
Now whenever you’re ready to deploy, you can just run yarn deploy
!
yarn deploy
or
npm run deploy
And your app will be available at the homepage listed in your package.json
—in my case, http://xtbc17s1.github.io/thing-list.
Firebase offers free hosting in addition to the database and authentication solutions that we’re already using. This again works quite well with create-react-app.
create-react-app includes detailed instructions for deploying with Firebase in the README.
First, install the command-line interface (CLI) for Firebase.
yarn global add firebase-tools
or
npm install -g firebase-tools
Now initialize Firebase in your project directory…
firebase init
… and follow the instructions from the create-react-app README.
If you’ve already configured your app to deploy to GitHub Pages, you need to remove the homepage
line from package.json
before deploying to Firebase.
React Router provides a routing solution that allows us to change what UI we render based on the current URL. The router is a Higher Order Component that wraps a React app and allows us to navigate without additional requests and responses to and from the server.
Setting up React Router is easy. For web projects, install react-router-dom
yarn add react-router-dom # install react router with yarn
or
npm install --save react-router-dom # install react router with npm
Then, in your ReactDOM.render
call, attach the Router as your base element, wrapping the root-level <App />
component. The whole app is now contained within the Router component, so we can take advantage of it anywhere.
index.js
import React from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter as Router } from 'react-router-dom'
import App from './App'
ReactDOM.render(
<Router>
<App />
</Router>,
document.getElementById('root')
)
The core of React Router is the <Route />
component. It allows you to specify what UI to render when a particular URL is matched. For instance, if we wanted to render a <Users />
component when we matched a /users
URL, we could make the following Route:
<Route path='/users' component={Users} />
If you don’t want to render a whole component, a Route can alternatively accept a render
prop, which accepts a function that returns JSX:
<Route path='/users' render={() => <h1>Users Path!</h1>} />
One important thing to keep in mind is that if we define a Route’s path as /users
, that will match both /users
and /users/123
, because both begin with /users
. If we want the Route to match only when the path is exactly /users
, we can add the prop exact
to our Route component.
<Route exact path='/users' component={Users} />
React Router also provides <Link />
and <NavLink />
components to make it easy to generate links to Routes. If we want to generate a Link that goes to /about
, we can do the following:
<Link to='/about'>About</Link>
NavLinks are similar, but provide some additional functionality. The main difference is that they will add an activeClassName
to the rendered link if the current URL matches the to
property of the NavLink. This allows active links to be styled differently than inactive links.
<NavLink to='/'>Home</NavLink> // rendered link tag will have '.active' class when URL is '/'
The history
object is maintained and updated by the Router to keep track of where the user has navigated within the app. It is passed to every component contained within the Router as part of the component’s props
. It has a variety of helpful properties and methods that provide information and navigation. Here are just a few:
history.length // number of history entries
history.location // provides the current location
history.push(path) // navigates to a new path
history.go(n) // navigates n steps through history stack
history.goBack() // go back one step (history.go(-1))
history.goForward() // go forward one step (history.go(1))
history.block(prompt) // block navigation
The Fetch API provides a JavaScript interface for accessing and manipulating parts of the HTTP pipeline, such as requests and responses. It also provides a global
fetch()
method that provides an easy, logical way to fetch resources asynchronously across the network.
If we need to get data from a remote server (or send some to one), there are several ways to do it. In vanilla JS, there is XMLHttpRequest
, jQuery provides $.ajax
, and there are a variety of other packages and libraries that provide their own version. Luckily, there is a new kid in vanilla JS town - the Fetch API.
fetch()
is a globally available, easy to use way to asynchronously send and receive data. The simplest usage of fetch is to simply provide it with the URL of the request, and it will perform a GET
request by default. The fetch()
function returns a promise that resolves when the data is received. Once it is received, we can process and use the data with functions provided to the promise’s .then()
callbacks.
fetch('https://api.mywebsite.com/users') // fetch users data from 'mywebsite' api
.then(response => response.json()) // parse the response json into JavaScript object(s)
.then(users => console.log(users)) // log the parsed users to the console
.catch(error => console.warn(error)) // if any errors occur, log them to the console
If no second argument is provided to fetch()
, it defaults to a standard GET
request. However, the second argument can be a configuration object, allowing it to use different HTTP methods, set Headers, include Credentials, etc. To find out more, check out the docs
Extend the API-Party app by adding at least one additional route that gets data from a public API.