Applying states to single-page application
We want to continue what we started in the previous chapter in building a single-page application. We couldn't finish it back then because we lacked a way to switch to a different page other than the home page. We had put together a Nav
component:
const Nav = ({ items, selected }) => { ... }
Given a list of pages, the Nav
component displays them as links to navigate. The currently selected
page needs to be provided as well. Now that we know how to define a state, let's use it to keep track of the selected
page:
const App = () => { const selected = _getM("home") return ( <div> <Nav items={menus} selected={selected} onSelect={_setM} /> ... </div> ) }
In the preceding App
component, we used a state for selected
to hold the home
key initially, which is then passed into the Nav
component. To allow the state to be updated after a user click, we need to modify Nav
by adding the support of an onSelect
callback function:
const Nav = ({ items, selected, onSelect }) => { const isActive = item => item.key === selected const onClick = item => () => { onSelect(item.key) } ... }
In the preceding amended Nav
component, an onSelect
prop is passed so that after onClick
, the parent App
component can be notified to update the selected
page via the _setM
function.
To confirm that the user does reach a different page, based on the current selected page, we can use a Route
component to switch between page content:
const Route = ({ selected }) => { return ( <div> {selected === 'home' && <Home />} {selected === 'product' && <Product />} </div> ) }
What the preceding Route
component does is display the page content based on the selected
page. Note that it uses a &&
symbol, which is a common line in React code. It's equivalent to the following:
{selected === 'home' ? <Home /> : false}
If the condition matches on the left part, it returns <Home />
; otherwise, it returns false
. And according to React, any true
, false
, null
, or undefined
values are all valid elements, but when updated, they all get ignored without being displayed. Essentially, if the left part condition doesn't meet, it displays nothing.
Putting the Nav
and Route
components together, we can amend the App
component:
const Home = () => <h1>Home page</h1> const Product = () => <h1>Product page</h1> const App = () => { const selected = _getM("home") return ( <div> <Nav items={menus} selected={selected} onSelect={_setM} /> <Routes selected={selected} /> </div> ) }
Finally, we got two pages working, as shown in Figure 2.10! If you click the Product link, it'll land on the product page:
To recap, the App
component defines a selected
state to hold the currently selected
page. The Nav
component is used to display all the links and allow it to choose a different page by clicking on the link. The Route
component is used to display a page based on the selected
state. Essentially, based on this setup, adding more pages is just a matter of adding new components under the Route
component.
Playground – Single-Page Application
Feel free to play with this example online at https://codepen.io/windmaomao/pen/PoKoWPG.
Before we end this chapter, let's take a minute to look at how exactly a state drives the UI under React.