-
Notifications
You must be signed in to change notification settings - Fork 3
10. Routing
Currently our application only has one screen. It would be great to add additional screens to the application, such as a homepage, where in the future we could set it up so that users could perform a search. We can modify our application to take advantage of rendering our initial application on the server but then any subsequent navigation will be handled by react. Meaning it changes will be done by the browser using javascript rather then requesting the server send back the next (page | screen) html.
From a high level we can visualize interaction's like this for a traditional web application:
And like this for a universal | isomorphic application Where with pages that have no API data requirements we can just render instantaneously via javascript. Under certain scenario's that has allowed us to go from page load speeds that took [18 seconds to 2 seconds](https://community.rea-group.com/blogs/tom/2016/10/10/unpacking-the-new-sold-experience-performance) with our re-platformed [application](https://www.realestate.com.au/sold/list-1)- Add a homepage which has a link to our results page of properties
- Add a link back to the homepage from the results page
- Which ever page we load first should be rendered by the server
- Any subsequent page we navigate to should be rendered by the client.
- A Routing solution such as react-router will make this a lot easier
yarn add react-router
to transition between different screens. Before we start trying to integrate it into our current solution we should take at how it works in a simple scenario.
// client/index.js
import { Router, Route, browserHistory } from 'react-router'
render(
<Router history={browserHistory}>
<Route path="/" component={App}>
<Route path="about" component={About}/>
<Route path="something-else/:id" component={SomeOtherScreen}/>
</Route>
</Router>
);
//App Component
...
render(
<div>
<Header />
{ this.props.children }
<Footer />
</div>
);
//About Component
...
render(
<div>
About our company...
</div>
);
- Router is the top level component that allows us to render different Components when the URL changes
- browserHistory is the underlying mechanism which we pass to the instance of react router created to listen to url changes. It uses the history API to do this. There are other ways this can be done, but this is the way that is relevant to us.
- Route has the following props
-
path
is the URL that we match against to render a -
component
the react component we assign to the Route.
-
To push changes to your store redux uses the concept of dispatching. Through this paradigm achieves a one way data flow, and we can see this represented by the following diagram:
In complex applications one way data flow can simplfy the mental model we have for application state. In our use case we will be dispatching actions that update the API data within it's reducer when the user navigates the application.- We want to change the express method that assigns the
middleware
to useuse
rather thenget
as we now want to routing to react router. This will mean any path that's not matched in one of the previous express configs will be run through./src/server/middleware.js
- Using a static method fetchData we are able to co-locate the API call to the component that requires that data, although the as we have seen the API call is made higher up. Now that we have multiple route's and screens which are matched dynamically we need a way to find the 'active routes' fetchData method.
const emptyPromise = () => Promise.resolve();
const fetchData = ({ routes }) => {
const matchedRoute = routes[routes.length - 1];
const fetchData = matchedRoute.fetchData || emptyPromise;
return fetchData();
}
fetchData(routingState)