Lesson 9 - React 2: More Hooks, Libraries, Styling, and Routing
Introduction​
Welcome to the second React lesson of the course! In this reading, we'll begin
with a review of hooks and the useState
hook which we covered in our last
reading. We'll then dive into the useEffect
hook. Together, useState
and
useEffect
are extremely powerful, and are probably the only 2 hooks you'll
need in this course.
After looking at hooks, we'll delve into how styling works in React, covering a couple ways that you can use to ensure that your React apps look as beautiful as your websites did in the first part of the course.
Next, we'll dive into the notion of libraries in React and the powerful ecosystem that surrounds it. From there, we'll cover component libraries, a powerful way to write less code and create stunning UI's in minutes as compared to hours.
Finally, we'll touch upon routing and how to easily add multiple pages to your websites in React.
useEffect​
Let's start with a quick review of hooks!
Hook review​
useEffect
is a hook. Hooks in React manage the state of your application.
Essentially, hooks are functions that let you “hook into” React state and
lifecycle features from functional components. React provides a few built-in
Hooks like useState
. You can also create your own Hooks to reuse stateful
behavior between different components. In the
React 1 Reading, you learnt about the useState
hook,
which we used to initialize a variable, along with an updater function for that
variable. Let's do a quick review of useState
before moving on.
useState Review​
Let's recreate a counter example, just like we did in the React 1 Reading.
This example renders a counter. When you click the button, it increments the
value of count
.
import React, { useState } from 'react';
const Counter = () => {
// Declare a new state variable, which we'll call "count"
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
</div>
);
};
Here, useState
is a Hook. We call it inside of a functional component in React
to manage the state of our application. useState
returns a pair: the current
state value and a function that lets you update it. You can call this function
from anywhere to update the current state value. In our example above, we
initialized count
to have a starting state value of 0
and setCount
to a
function which updates our count
variable. The only argument to useState
is
the initial state. In the example above, it is 0 because our counter starts from
zero.
What Do Square Brackets Mean?​
You might have noticed the square brackets when we declare a state variable:
const [count, setCount] = useState(0);
The names on the left aren’t a part of the React API. You can name your own state variables:
const [fruit, setFruit] = useState('banana');
This JavaScript syntax is called “array destructuring”. It means that we’re
making two new variables fruit
and setFruit
, where fruit
is set to the
first value returned by useState
, and setFruit
is the second. It is
equivalent to this code:
var fruitStateVariable = useState('banana'); // Returns a pair
var fruit = fruitStateVariable[0]; // First item in a pair
var setFruit = fruitStateVariable[1]; // Second item in a pair
When we declare a state variable with useState
, it returns a pair — an array
with two items. The first item is the current value, and the second is a
function that lets us update it. Using [0]
and [1]
to access them is a bit
confusing because they have a specific meaning. This is why we use array
destructuring instead.
Declaring Multiple State Variables​
Declaring state variables as a pair of [something, setSomething]
is also handy
because it lets us give different names to different state variables if we want
to use more than one:
const ExampleWithManyStates = () => {
// Declare multiple state variables!
const [age, setAge] = useState(42);
const [fruit, setFruit] = useState('banana');
const [todos, setTodos] = useState([{ text: 'Learn Hooks' }]);
// ...
};
In the above component, we have age
, fruit
, and todos
as local variables,
and we can update them individually:
function handleOrangeClick() {
setFruit('orange');
}
You don’t have to use many state variables. State variables can hold objects and arrays just fine, so you can still group related data together.
Using useEffect​
Importing useEffect​
Similar to useState
and any other hook we might want to use, we import
useEffect
like so.
import React, { useState, useEffect } from 'react';
If we just wanted to import useEffect
and not useState
, we would do the
following:
import React, { useEffect } from 'react';
Counter Example​
The useEffect
hook lets you perform side effects in function components:
import React, { useState, useEffect } from 'react';
function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
// Update the document title using the browser API
document.title = `You clicked ${count} times`;
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
</div>
);
}
This code snippet is based on on our previous counter example, but we added a new feature to it: we set the document title to a custom message including the number of clicks.
Data fetching, setting up a subscription, and manually changing the DOM in React components are all examples of side effects.
Sometimes, we want to run some additional code after React has updated the DOM. Network requests, manual DOM mutations, and logging are some common examples of effects.
Details​
What does useEffect
do? By using this Hook, you tell React that your
component needs to do something after render. React will remember the function
you passed (we'll refer to it as our "effect"), and call it later after
performing the DOM updates. In this effect, we set the document title, but we
could also perform data fetching or call some other imperative API.
Why is useEffect
called inside a component? Placing useEffect
inside the
component lets us access the count
state variable (or any props) right from
the effect. We don't need a special API to read it -- it's already in the
function scope.
Does useEffect
run after every render? Yes! By default, it runs both after
the first render and after every update. (We will later talk about how to
customize this). Instead of thinking in terms of "mounting" and "updating", you
might find it easier to think that effects happen "after render". React
guarantees the DOM has been updated by the time it runs the effects.
Now that we know more about effects, these lines should make sense:
function Example() {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `You clicked ${count} times`;
});
}
We declare the count
state variable, and then we tell React we need to use an
effect. We pass a function to the useEffect
Hook. This function we pass is
our effect. Inside our effect, we set the document title using the
document.title
browser API. We can read the latest count
inside the effect
because it's in the scope of our function. When React renders our component, it
will remember the effect we used, and then run our effect after updating the
DOM. This happens for every render, including the first one.
General Usage​
Now that we've learnt the basics of hooks and useEffect
, lets take another
look at how to use useEffect
in a more general setting. The general format of
auseEffect
hook is as follows.
useEffect(() => {
// put your code here
}, dependencies);
Essentially, useEffect
is a function that takes in two arguements. The first
arguement is a function with what you want your useEffect
hook to do. This
function takes in no arguements, hence the empty brackets at the beginning of
our passed in arrow function. The second arguement, which is optional, is an
array of dependencies. For example, let's say that inside of our useEffect
hook, we want to update our score
variable, but only if the referee
variable
has changed. It would look something like this:
useEffect(() => {
setScore(someNewScore);
}, [referee]);
Thus we only setScore
to our new score value if the referee
variable
changes. If we wanted to set it so that we only updated the score based on
either the referee
variable or the inning
variable changing, we could do
something like this.
useEffect(() => {
setScore(someNewScore);
}, [referee, inning]);
Running useEffect on First render​
If the useEffect
hook seemed confusing to you, that's totally fine! Just make
sure to pay attention here.
If you want to update something in your app, or have something happen right at page load, you can put it into the useEffect function, and pass in an empty array into it's list of dependencies. For example, say I wanted to print "Hello World" to the console right at page load. I would do the following.
useEffect(() => {
console.log('Hello World');
}, []);
Notice the empty array that was passed into the second arguement of our
useEffect
. This ensures that whatever's in our useEffect
function only runs
on page load. This will come up more often than not when you're building and
testing any future projects.
Styling in React​
There are many, many ways to style your components and JSX code in React. In this reading we'll talk about Tailwind CSS with Vivid, CSS-in-JS, CSS Modules, and Styled Components.
Tailwind CSS​
Tailwind CSS is a utility-first CSS framework. This means that instead of writing traditional global CSS like background-color: #f63344
, you apply styles in-line via small “utility classes” like p-4
for padding or bg-red-500
for a red background.
Each of these utility classes is atomic, so they only apply one style rule at a time. While you can use them to write arbitrary CSS using their arbitrary notation (e.g., bg-[#f63344]
), most of the time you’ll be using the color and sizing scales that Tailwind provides for you. All of these features can also be easily configured be changing your tailwind.config.js
.
Why Use Tailwind​
Tailwind offers benefits for beginners and experts alike!
For beginners or simple applications, Tailwind is a fast way to write all your styling inline. By not having to deal with the abstraction of component-based classnames or fine-tuning colors and pixel values, you can move faster with Tailwind than with alternative CSS frameworks.
For more advanced use-cases, Tailwind forms a useful part of a design system by streamlining modularity and reducing unneeded abstractions. Since Tailwind lets you configure a set of common sizes, colors, and utilities, you can easily write consistent styling across your app. By removing modularity at the CSS level (since styling is done inline), you can focus on just making your React code modular.
To prevent long class strings at all levels of your code, you generally have to be more thoughtful about your component modularity when using Tailwind CSS.
Installation​
The official Tailwind installation guide does a great job of walking you through the easy 4 step setup. You can follow the “PostCSS” or “Framework Guides” sections there to get started.
Usage​
Once Tailwind is set up, you can use any of the classes in their docs right in your code:
<h1 class="text-3xl font-bold underline">
Hello world!
</h1>
This snippet makes your heading large, bolded, and underlined — pretty self-explanatory!
Vivid​
Vivid is an in-browser visual editor that lets you test out Tailwind styles and automatically write them directly to your code.
With Vivid, you can click on any component in your page and have its code pop up right in your browser. From there, you can edit its code in the code pane, or preview and apply styles with shortcuts through the command palette.
Installation​
To summarize the Vivid docs:
- Install Vivid with
npm i -D vivid-studio
- Initialize it by pasting the following code at the top of your root file outside of any functions:
if (
typeof window !== "undefined" &&
process.env.NODE_ENV === "development"
) {
import("vivid-studio").then((v) => v.run());
import("vivid-studio/style.css");
}
Usage​
Once Vivid is set up, you just have to start your app in development mode (usually with npm run start
or npm run dev
). From there, Vivid will walk you through its functionality!
Instead of the usual loop of opening your IDE, looking for a component’s code, and testing out styles in the browser, you can just Cmd-Click (Windows/Linux: Ctrl-Click) any part of your page and start editing its code from your browser.
Once you get comfortable with editing code in the code pane, you can iterate through styles even faster with the command palette shortcuts Vivid provides (Cmd/Ctrl + K).

CSS-in-JS​
CSS-in-JS is a term you'll hear often, but what exactly does it mean? CSS-in-JS usually means using an alternative method of styling than just plain CSS files, such as styled-components or css-modules. These solutions often require some change in the javascript that is being written, which is why we call these solutions "CSS in JS".
Why do we care about using CSS-in-JS? This is because all CSS in our react app
is global. Say you have two components, Page1 and Page2. Even if you create
page1.css
and page2.css
and only import page1.css into your Page1 component,
all the classes you create in page1.css
will apply to your Page2 component as
well. Thus if you accidentally use the same class name across both components,
or use a class name multiple times anywhere in your app, the CSS rules you've
written in page1.css
will apply everywhere, which in most cases is highly
undesirable and can cause unintended and difficult to fix CSS collisions.
CSS Modules​
CSS modules transforms your CSS files from being globally scoped to being
component scoped, which means that the CSS you import into your component only
affects the component you've imported that CSS file into. To transform a CSS
file into a CSS modules file, simply change the file name from <file name>.css
to <file name>.module.css
. CSS modules also works with sass. In order to use
CSS modules in your app, make the following changes.
//Importing Regular CSS
import './styles.css';
//Using Regular CSS
<div className="container">
<h3>Hi There!</h3>
</div>;
//Importing CSS Modules
import styles from './styles.module.css';
//Using CSS Modules
<div className={styles['container']}>
<h3>Hi There!</h3>
</div>;
The difference in your JavaScript files is that you treat your CSS file as an object and access the class names the same way you would access an object's attributes, but that's it! Your CSS files remain the same and now there's no need to worry about annoying CSS collisions.
Installation​
CSS modules comes pre-installed with Create React App (sometimes referred to as CRA).
Documentation​
Styled Components​
Using styled components is a bit more tricky.
Why Use Styled Components​
- Write CSS in JS alongside HTML in JS, but don't have to inline the CSS
- Keeps track of which components are rendered on a page and injects their styles and nothing else, fully automatically.
- You never have to worry about duplication, overlap or misspellings. No need to keep track of class names.
- Adapting the styling of a component based on its props or a global theme is simple and intuitive without having to manually manage dozens of classes.
Installation​
npm i styled-components
Trying It Out​
In app.js
,
const Title = styled.h1`
font-size: 1.5em;
text-align: center;
color: palevioletred;
`;
const Wrapper = styled.section`
padding: 4em;
background: papayawhip;
`;
render(
<Wrapper>
<Title>Hello World!</Title>
</Wrapper>
);
The naming is as intuitive as it seems — Title
is an <h1>
tag, but with some
styles associated with it. Wrapper
is a div, but with some styles associated
with it. To add style, we no longer need to inline, we can simply change the
definition of Title
or Wrapper
.
Passing Arguments​
const Button = styled.button`
background: ${(props) =>
props.primary === true ? 'palevioletred' : 'white'};
color: ${(props) => (props.primary ? 'white' : 'palevioletred')};
font-size: 1em;
margin: 1em;
padding: 0.25em 1em;
border: 2px solid palevioletred;
border-radius: 3px;
`;
render(
<div>
<Button>Normal</Button>
<Button primary={true}>Primary</Button>
</div>
);
Documentation​
Component Libraries​
A UI component library is a set of ready-made UI components such as buttons, inputs, dialogs, and so on. They serve as building blocks for layouts. Thanks to their modular nature, we can arrange components in many different ways to achieve unique effects. Each library has a distinctive look and feel, but most of them offer theming, and their components are customizable to a certain degree.
Popular component libraries for React include React-Bootstrap, Theme UI, and Chakra UI. We'll be focusing on Chakra UI.
Libraries are made for one reason – to make developers’ lives easier. UI component libraries are no different in their purpose.
Benefits​
- Speed – incorporating a UI component library can have a great impact on development speed. Instead of creating each element from scratch, we simply mix and match the existing components. Even if some additional customization is required, it tends to be much quicker than writing styles on our own.
- Ease of use – components are meant to be easy to use. Established libraries are well-organized and have good documentation that is easy to follow. Very often, it’s enough just to copy and paste code snippets to make it work.
- Attractive look – components look great without requiring any extra effort from the developer; they’re carefully designed by professionals.
- Compatibility – ensuring cross-browser and cross-device compatibility is one of the biggest challenges of frontend development. UI component libraries provide compatibility out of the box, which makes everything so simple!
- Accessibility – good libraries adhere to accessibility guidelines, so developers don’t even need to think about it.
Drawbacks​
- Generic look – your app’s look and feel will be determined by the library’s style in most parts. This is not necessarily an issue, but you need to make sure that this is acceptable for your project.
- Change of design direction – It’s very important that designers understand and stick to components offered by the library. If the direction changes towards a custom solution, it will become increasingly difficult and time-consuming to overwrite the initial implementation.
- New team members – every developer and designer needs to be familiar with the particular library and its implementation (though this point is true for any design system and any project).
- Bundle size – UI component libraries tend to be big, so it’s probably not the best idea to engage them in tiny projects.
Chakra-UI​
Chakra UI is component library based on a few principles:
Style Props: All component styles can be overridden or extended via style props to reduce the use of css prop or styled(). Compose new components from Box.
Simplicity: Strive to keep the component API fairly simple and show real world scenarios of using the component.
Composition: Break down components into smaller parts with minimal props to keep complexity low, and compose them together. This will ensure that the styles and functionality are flexible and extensible.
Accessibility: When creating a component, keep accessibility top of mind. This includes keyboard navigation, focus management, color contrast, voice over, and the correct aria-* attributes.
Dark Mode: Make components dark mode compatible. Use useColorMode hook to handle styling. Learn more about dark mode.
Naming Props: We all know naming is the hardest thing in this industry. Generally, ensure a prop name is indicative of what it does. Boolean props should be named using auxiliary verbs such as does, has, is and should. For example, Button uses isDisabled, isLoading, etc.
For more info on Chakra versus other component libraries, check out their docs.
Installation​
yarn add @chakra-ui/react @emotion/react@^11 @emotion/styled@^11 framer-motion@^5
Setup Provider​
import * as React from 'react';
// 1. import `ChakraProvider` component
import { ChakraProvider } from '@chakra-ui/react';
function App({ Component }) {
// 2. Use at the root of your app
return (
<ChakraProvider>
<Component />
</ChakraProvider>
);
}
Incorporating​
React-Bootstrap​
React-Bootstrap is a complete re-implementation of the Bootstrap components
using React. It has no dependency on either bootstrap.js
 or jQuery. If you
have React setup and React-Bootstrap installed, you have everything you need.
Methods and events using jQuery are done imperatively by directly manipulating the DOM. In contrast, React uses updates to the state to update the virtual DOM. In this way, React-Bootstrap provides a more reliable solution by incorporating Bootstrap functionality into React's virtual DOM.
Installation​
yarn add react-bootstrap bootstrap
Incorporating Bootstrap​
import React, { Component } from 'react';
import Alert from 'react-bootstrap/Alert';
const Example = () => {
return (
<Alert dismissible variant="danger">
<Alert.Heading>Oh snap! You got an error!</Alert.Heading>
<p>Change this and that and try again.</p>
</Alert>
);
};
export default Example;
Don't worry if you don't get what's going on here — you don't need to remember Bootstrap (and by extension ReactBootstrap!) Whatever you don't understand in the above block of text, google it!
Documentation​
Other Libraries (Optional)​
There are many component libraries I haven't covered, and oftentimes larger projects and companies may create their own to fit their needs. I've included some other popular component libraries below. No component library is necessarily better than another, and each has pros and cons.
Material-UI: A popular React UI framework
Google's component library. The main complaint to using Material UI is that it's hard to customize and can thus leave some sites using a large amount of Material UI looking too much like something from Google.
Ant Design - The world's second most popular React UI framework
A library developed by the Chinese tech giant Alibaba.
Lightweight CSS frameworks such as Tailwind or Pure can also be considered as viable alternatives to a component library. They offer a minimal, less opinionated CSS foundation that will help you speed up development, while at the same time allowing tremendous flexibility.
Package Managers (Optional)​
What is NPM?​
npm
informally stands for node package manager. npm
is a package manager
for JavaScript and is the default package manager for Node.
It consists of a command-line client, also called npm, and an online database of public and paid-for private packages called the npm registry.
In order to install a package to use in your react project using npm, you run
npm install <name of package>
in the root directory of your react app. This
adds the package as a dependency in package.json
.
It is important to note that the package.json
is just a list of tools you are
using. It doesn't do anything except to list them. The real magic happens in the
node_modules
folder, where the packages are stored for you.
What is Yarn?​
Yarn is a package manager released by Facebook in 2016 and is a common alternative to NPM.
To install a package using yarn, run yarn add <name of package>
in the root
directory. **
NPM vs Yarn​
And now, to have an age-old discussion — which one should you use?
In practice, there is no real difference between the effects of using NPM
and yarn
, as both package managers work perfectly fine.
Back in the day, npm used to be super buggy, so yarn was created as a solution to NPM's deficiencies. These days the people behind npm were able to fix the main complaints people had against NPM, but many people and companies still prefer yarn as a byproduct of that era. There are definitely still advantages to using yarn, such as:
- Installing packages using yarn tends to be faster than installing packages with npm
- There are some slight security advantages to using yarn
but there are no other drastic differences between the two package managers. I personally use yarn and recommend yarn to others starting projects, but the choice is entirely up to you. Make sure you don't use both, however, because that can cause some problems on the backend when attempting to host your app.
If you are using npm, you should see a package-lock.json
in your app. If you
are using yarn, you should see a yarn.lock
in your app.
React Router​
We've learned about state, hooks, and components, and now we can build a nice single-page web app (commonly referred to as a SPA).
But now what? Most websites have multiple pages and some even have dynamic routes, routes that use data to determine what's shown to the user.
Think about youtube. The homepage showing you all the suggestions of videos you
might want to see is youtube.com
. At the same time, however, each video must
have its own route. Instead of having some poor intern create a route for each
video on youtube manually, we can use dynamic routing to display countless
similar pages by using a variable in the URL that's determined by the video or
piece of content that was clicked on. We can then go to that page and pull the
variable from the URL to determine which piece of content to display.
To be doing all this, we'll be using React Router. React Router is by far the most popular client-side router in the React community. It is mature, being used by big companies, and battle-tested at large scales. It also has a lot of really cool capabilities, some of which we'll examine here.
More on Routing
If you want to learn more about client-side routing and its alternative, server-side routing, check out this resource.
Documentation​
React router documentation can be found here.
Installation​
yarn add react-router-dom
Why use Routers?​
Why use a React Router at all? Didn't the <a>
work? It did but with a flaw:
every link you clicked would end up in the browser navigating to a whole new
page which means React would totally reload your entire app all over again. With
Routers, and its special features, it can intercept this and just handle that
all client-side. Much faster and a better user experience. The base URL and page
never actually change.
React Router is, at the end of the day, a conditional rendering wrapper that only shows you the component associated with the link you've selected or are on.
Basic Routing​
Let's implement a basic example of routing.
Introducing a New Tag Introducing a new tag: <nav>
! It is intended to
wrap major navigation blocks on your webpage. Here's more information about it.
import React from 'react';
import { BrowserRouter, Switch, Route, Link } from 'react-router-dom';
const App = () => {
return (
<BrowserRouter>
<div>
{/* The HTML */}
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/users">Users</Link>
</li>
</ul>
</nav>
{/* The React Router that makes the HTML above work */}
<Switch>
<Route path="/about">
<About />
</Route>
<Route path="/users">
<Users />
</Route>
<Route path="/">
<Home />
</Route>
</Switch>
</div>
</BrowserRouter>
);
};
const Home = () => <h2>Home</h2>;
const About = () => <h2>About</h2>;
const Users = () => <h2>Users</h2>;
export default App;
Dynamic Routing​
What if we have too many routes to write down manually? For example, what if we want a route for every listing on Airbnb? Here's where dynamic routing comes into play.
We can set our routes to use a variable by simply putting a colon in front of
the term we want to use as a variable in our route. See the example below where
we use :id
in our route, creating a variable id
that is then later accessed.
import React from 'react';
import {
BrowserRouter as Router,
Switch,
Route,
Link,
useParams,
} from 'react-router-dom';
function DynamicRouting() {
const data = [
{ name: 'Netflix', route: 'netflix' },
{ name: 'Zillow', route: 'zillow' },
{ name: 'Yahoo', route: 'yahoo' },
{ name: 'Instagram', route: 'instagram' },
];
return (
<Router>
<div>
<h2>Accounts</h2>
<div>
{data.map((item) => (
<Link to={`/${item.route}`}>
<div>
<h3>{item.name}</h3>
</div>
</Link>
))}
</div>
<Switch>
<Route path="/:id" children={<Child />} />
</Switch>
</div>
</Router>
);
}
function Child() {
let { id } = useParams();
return (
<div>
<h3>{id}</h3>
</div>
);
}
export default DynamicRouting;
As you can see, we use /:id
as a variable route, or a dynamic route rather
than a static route. There is no path /id
(unless we want there to be),
rather, the id
variable is a URL parameter, or param. We specifically the
children of the /:id
route in our <Route>
tag, and this component is what
will be rendered to the user. As we can see above, the Child
component changes
what it displays depending on the route that it is displayed from. We can grab
the id
param from the URL by using the useParams
hook as shown in the
example, then proceed to use it as a variable in our component.
To add an example, say you were looking at a list of cards in airbnb, each with
basic listing info on them. When you want to learn more about a listing, you
clock on that card, which then takes you to another page with more complete info
about that listing. Relating that action to dynamic routing, each listing has a
unique id. The browser takes you to a URL with that id when you click on a card.
In this way Airbnb implements dynamic routing, setting the URL to the id of the
listing you chose. Next, the router realizes that it has a dynamic route
(/listing/12345
might match to /listing/:id
for example) and renders that
route's assigned component, which we'll call Listing
. Listing
then uses
hooks such as useParam
to determine the id of the requested listing, then
queries Airbnb's database to get the info for that listing before displaying it
to the user.
Complex Routing — A Practical Example (Optional)​
I've included an example from the WDB website below.
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
import Navbar from './components/navbar';
import Footer from './components/footer';
import Landing from './pages/landing';
import About from './pages/about';
import Initiatives from './pages/initiatives';
import Error from './pages/error';
import './App.scss';
function App() {
return (
<Router>
<Switch>
<Route exact path="/">
<Navbar landing />
</Route>
<Route path="*">
<Navbar />
</Route>
</Switch>
<Switch>
{/* About Us */}
<Route path="/about">
<About />
</Route>
{/* Initiatives */}
<Route path="/initiatives">
<Initiatives />
</Route>
{/* Landing Page */}
<Route exact path="/">
<Landing />
</Route>
{/* 404 no page found */}
<Route path="*">
<Error />
</Route>
</Switch>
<Footer />
</Router>
);
}
export default App;
Let's take a closer look at the following snippet from the above
<Switch>
<Route exact path="/">
<Navbar landing />
</Route>
<Route path="*">
<Navbar />
</Route>
</Switch>
The exact
prop tells our router to only show the landing version of the navbar
when there are no extensions to the URL, which makes sense since we want our
landing page to be the default page. Using *
as the path for our regular
navbar tells the router that for all other pages, render the regular navbar.
info
Using a single variable as a prop (such as exact
or landing
above) is
equivalent to setting exact={true}
or landing={true}
as a prop. Thus we just
use exact
or landing
instead of the whole statement as shorthand.
Conclusion​
This lesson is all about helping you realize that the React universe is massive, collaborative, and full of tools that make writing React faster and easier. There are many more tools to the React ecosystem that we were unable to touch on today and that you may not need at any point in the course, but keep in mind that if you're trying to solve a general problem or create something specific, there's probably an npm package for that.
Contributors