# Lesson5: React Router: Lesson Summary
###### tags: `Recat`
# React Router Intro
{%youtube PV6TN8ahSX0%}
## Single-Page Apps
Single-page applications can work in different ways. One way a single-page app loads is by downloading the entire site's contents all at once. This way, when you're navigating around on the site, everything is already available to the browser, and it doesn't need to refresh the page. Another way single-page apps work is by downloading everything that's needed to render the page the user requested. Then when the user navigates to a new page, asynchronous JavaScript requests are made for just the content that was requested.
Another key factor in a good single-page app is that the URL controls the page content. Single-page applications are highly interactive, and users want to be able to get back to a certain state using just the URL. Why is this important? Bookmarkability! (pretty sure that's not a word...yet) When you bookmark a site, that bookmark is only a URL, it doesn't record the state of that page.
Have you noticed that any of the actions you perform in the app do not update the page's URL? We need to create React applications that offer bookmarkable pages!
## React Router
React Router turns React projects into single-page applications. It does this by providing a number of specialized components that manage the creation of links, manage the app's URL, provide transitions when navigating between different URL locations, and so much more.
According to the React Router website:
> React Router is a collection of **navigational components** that compose declaratively with your application.
If you're interested, feel free to check out the website at https://reacttraining.com/.
In the next section, we'll dynamically render content to the page based on a value in the project's `this.state` object. We'll use this basic example as an idea of how React Router works by controlling what's being seen via state. Then we'll switch over to using React Router. We'll walk you through installing React Router, adding it to the project, and hooking everything together so it can manage your links and URLs.
# Dynamically Render Pages
We don't want the form to display all of the time, so we'll start out by having the form show up only if a setting is enabled. We'll store this setting in `this.state`. Doing it this way will give us an idea of how React Router functions.
{%youtube =I4wTc_ulrME%}
[Here's the commit with the changes made in this video.](https://github.com/udacity/reactnd-contacts-app/commit/e4a527dbd7a5e1d3fca2a92251556024d834258a)
We packed quite a bit of important changes in this little video! We created the CreateContact component that'll be in charge of the form to create new contacts. In staying with the general React theme of favoring composition, we created this as a standalone component and used composition by adding it to the `render()` method in the `App` component.
In an attempt to do an extremely simple recreation of how React Router works, we added a `screen` property to `this.state`, and used this property to control what content should display on the screen. If `this.state`.screen is `list` then we'll show the list of all existing contacts. If `this.state.screen` is `create` then we'll show the CreateContact component.
## Short-circuit Evaluation Syntax
In this video and when we created the Now showing section from earlier, we used a somewhat odd looking syntax:
```javascript
{this.state.screen === 'list' && (
<ListContacts
contacts={this.state.contacts}
onDeleteContact={this.removeContact}
/>
)};
```
and
```javascript
{this.state.screen === 'create' && (
<CreateContact />
)}
```
This can be a little confusing with both the JSX code for a component and the code to run an expression. But this is really just the logical expression `&&`:
```javascript
expression && expression
```
What we're using here is a JavaScript technique called **short-circuit evaluation**. If the first expression evaluates to `true`, then the second expression is run. However, if the first expression evaluates to `false`, then the second expression is skipped. We're using this as a guard to first verify the value of `this.state.screen` before displaying the correct component.
For a deeper dive into this, check out [the short-circuit evaluation info on MDN.](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators#Short-circuit_evaluation)
## Add A Button
Right now we have to manually change the state to get the app to display the different screens. We want the user to be able to control that in the app itself, so let's add a button!
{%youtube AX-ZpaliAYc%}
[Here's the commit with the changes made in this video.](https://github.com/udacity/reactnd-contacts-app/commit/93ff543181f0558ee5be9aab8eef771c47269451)
Dynamic Routing Recap
In the code we added in this section, we tried our attempt at using state to control what content displays to the user. We saw things break down, though, when we used the back button.
Now, let's switch over to using React Router to manage our app's screens.
# The BrowserRouter Component
As we've just seen, when the user presses the 'back' button in the browser, they will probably have to refresh the page to see the proper content at that location. This isn't the best experience for our user! When we update location, we can update the app as well using JavaScript. This is where React Router comes in.
## Install React Router
To use React Router in our app, we need to install react-router-dom.
```
npm install --save react-router-dom
```
Let's see it in action!
{%youtube qvy-_Pu9QNU%}
[Here's the commit with the changes made in this video.](https://github.com/udacity/reactnd-contacts-app/commit/fbd0cea0839d018209a19d468fc1661da9f9033a)
## BrowserRouter
The first component we'll look at is BrowserRouter.
{%youtube bhjvF7Qt7K0%}
{%youtube uIYOoQKwKfU%}
[Here's the commit with the changes made in this video.](https://github.com/udacity/reactnd-contacts-app/commit/d1b067febbfc467563742fc3b52b6a34486ebde5)
What's nice about React Router is that everything is just a component. This makes using it nice, but it also makes diving into the code more convenient as well. Let's take a look at what exactly BrowserRouter is doing under the hood.
Here is the code straight from the React Router repository.
```javascript
class BrowserRouter extends React.Component {
static propTypes = {
basename: PropTypes.string,
forceRefresh: PropTypes.bool,
getUserConfirmation: PropTypes.func,
keyLength: PropTypes.number,
children: PropTypes.node
}
history = createHistory(this.props)
render() {
return <Router history={this.history} children={this.props.children} />
}
}
```
When you use `BrowserRouter`, what you're really doing is rendering a `Router` component and passing it a `history` prop. Wait, what is `history`? `history` comes from the [history](https://github.com/ReactTraining/history) library (also built by React Training). The whole purpose of this library is it abstracts away the differences in various environments and provides a minimal API that lets you manage the `history` stack, navigate, confirm navigation, and persist state between sessions.
So in a nutshell, when you use BrowserRouter, you're creating a `history` object which will listen to changes in the URL and make sure your app is made aware of those changes.
## `BrowserRouter` Component Recap
In summary, for React Router to work properly, you need to wrap your whole app in a `BrowserRouter` component. Also, `BrowserRouter` wraps the history library which makes it possible for your app to be made aware of changes in the URL.
**Further Research**
- [history](https://github.com/reacttraining/history)
# The Link Component
{%youtube EZVVkrODWw8%}
{%youtube jrW6zIa0Qdc%}
[Here's the commit with the changes made in this video.](https://github.com/udacity/reactnd-contacts-app/commit/1197d9d7bb255f2ff17eed63d295a80014c26814)
As you've seen, `Link` is a straightforward way to provide declarative, accessible navigation around your application. By passing a `to` property to the `Link` component, you tell your app which path to route to.
```javascript
<Link to="/about">About</Link>
```
If you're experienced with routing on the web, you'll know that sometimes our links need to be a little more complex than just a string. For example, you can pass along query parameters or link to specific parts of a page. What if you wanted to pass state to the new route? To account for these scenarios, instead of passing a string to `Link`s to `prop`, you can pass it an object like this,
```javascript
<Link to={{
pathname: '/courses',
search: '?sort=name',
hash: '#the-hash',
state: { fromDashboard: true }
}}>
Courses
</Link>
```
You won't need to use this feature all of the time, but it's good to know it exists. You can read more information about `Link` in the [official docs](https://reacttraining.com/react-router/web/api/Link).
## Link Recap
React Router provides a `Link` component which allows you to add declarative, accessible navigation around your application. You'll use it in place of anchor tags (`a`) as you're typically used to. React Router's `<Link>` component is a great way to make navigation through your app accessible for users. Passing a to prop `to` your link, for example, helps guide your users to an absolute path (e.g., `/about`):
```javascript
<Link to="/about">About</Link>
```
Since the `<Link>` component fully renders a proper anchor tag (`<a>`) with the appropriate `href`, you can expect it to behave how a normal link on the web behaves.
**Further Research**
- `<Link>` at React Training
- [Source Code](https://github.com/ReactTraining/react-router/blob/master/packages/react-router-dom/modules/Link.js)
# The Route Component
{%youtube ocZkC0MqGPY%}
{%youtube Ka19h7gvKi0%}
[Here's the commit with the changes made in this video.](https://github.com/udacity/reactnd-contacts-app/commit/66dcafce787f673b80622f808ca2dc4236aef0b0)
## Route Component Recap
The main takeaway from this section is that with a `Route` component if you want to be able to pass props to a specific component that the router is going to render, you'll need to use `Route`’s `render` prop. As you saw, `render` puts you in charge of rendering the component which in turn allows you to pass any props to the rendered component as you'd like.
In summary, the `Route` component is a critical piece of building an application with React Router because it's the component which is going to decide which components are rendered based on the current URL path.
# Create The Contact Form
Right now, the page to create contacts is empty! Let's build out a form on that page so we start adding our own custom contacts.
> ⚠️ Required File ⚠️
> At the beginning of the program, we gave you the option to clone our starter project or to start from scratch using [create-react-app](https://github.com/facebookincubator/create-react-app). If you haven't added it yet, you'll need [the ImageInput.js file](https://github.com/udacity/reactnd-contacts-complete/blob/master/src/ImageInput.js) for the following video.
The ImageInput component is a custom `<input>` that dynamically reads and resizes image files before submitting them to the server as data URLs. It also shows a preview of the image. We chose to give this component to you rather than build it ourselves because it contains features related to files and images on the web that aren't crucial to your education in this context. If you're curious, feel free to dive into the code, but know it's not a requirement.
{%youtube p3v2dgrqJsg%}
[Here's the commit with the changes made in this video.](https://github.com/udacity/reactnd-contacts-app/commit/4b1693fa9b8268af8f1eb190d0bae66bf850ffb4)
## Serialize The Form Data
At this point, our form will serialize the values from user input (i.e., the `name` and `email`), adding them as a query string to the URL. We can add some additional functionality by having our app serialize these form fields on its own. After all, we want the app to ultimately handle creating the contact and saving it to the state.
To accomplish this, we'll use the [form-serialize](https://www.npmjs.com/package/form-serialize) package to output this information as a regular JavaScript object for the app to use.
```
npm install --save form-serialize
```
Let's see it all in action!
{%youtube aAhaXlQ2G6I%}
[Here's the commit with the changes made in this video.](https://github.com/udacity/reactnd-contacts-app/commit/69c8b52ff523071db4ed9c5edb07aa34445d1570)
## Update Server With New Contact
We have our contact form. We're serializing our data and passing it up to the parent component. All we need to do to have a fully functional app is to save the contact to the server.
{%youtube 24lu6iVQHro%}
[Here's the commit with the changes made in this video.](https://github.com/udacity/reactnd-contacts-app/commit/f876f2d17b338e57ec80e8f67abbb3efa83bff2a)
# React Router Outro
{%youtube 3oyeoXXB2qA%}
**Further Learning**
If you're interested in learning more about React Router, we recommend these two resources. First, [Build your own React Router v4](https://tylermcginnis.com/build-your-own-react-router-v4/) will walk through how to implement your own mini version of React Router to better understand its implementation details. Next, is React Training's [official documentation](https://reacttraining.com/react-router/web/guides/philosophy) for React Router. Feel free to also check out Tyler McGinnis's [React Router](https://tylermcginnis.com/courses/react-router/) course as well!
## Lesson Challenge
Read Tyler's [Nested routes with React Router v4](https://tylermcginnis.com/react-router-nested-routes/) blog post and answer the following questions. Share your answers with your classmates.
1) What is the difference between `Link` and `Route`?
2) What is the difference between `match.path` and `match.url`? Give a use case for each.
3) Create a code example where you (1) pass props to a component that's rendered by React Router and (2) use nested routes.
# Course Outro
{%youtube EvPfR_06CF8%}
## Keep Learning
Great work! You've learned how to build applications in React, but there's always more to learn! Check out the following resources to up your skills:
- [The React Docs](https://facebook.github.io/react/docs/hello-world.html)
- [Tyler's Blog](https://tylermcginnis.com/)
## People to Follow
Whether it be popular blog posts or developers to follow on Twitter, a large part of getting everything out of a new technology is utilizing existing community resources. So we want to share with you with our favorite resources from the React community that we've found helpful over the last few years. Hopefully you'll find them helpful as well.
- [Dan Abramov](https://twitter.com/dan_abramov)
- [Sebastian Markbåge](https://twitter.com/sebmarkbage)
- [Henry Zhu](https://twitter.com/left_pad)
- [Peggy Rayzis](https://twitter.com/peggyrayzis)
- [Merrick Christensen](https://twitter.com/vjeux)
- [Christopher Chedeau](https://twitter.com/vjeux)
- [React](https://twitter.com/reactjs)
- [Tyler McGinnis](https://twitter.com/tylermcginnis)
## Blog posts to read
- [You're missing the point of React](https://medium.com/@dan_abramov/youre-missing-the-point-of-react-a20e34a51e1a)
- [React "Aha" Moments](https://tylermcginnis.com/react-aha-moments/)
- [9 Things every React.js Beginner should know](https://camjackson.net/post/9-things-every-reactjs-beginner-should-know)
- [React Elements vs React Components](https://tylermcginnis.com/react-elements-vs-react-components/)
If you want to learn more advanced topics in React, you can check out [tylermcginnis.com](https://tylermcginnis.com/).
Thanks for joining us on this journey! Now it's time to move on to learning Redux!
Here's how what you've learned thus far maps to your career:
