-
Notifications
You must be signed in to change notification settings - Fork 2
Set up Routes
As of now, we have an empty ContactList and a ContactForm wrapped into a ContactCreate component that
we still haven't rendered and tested yet. To be able to access the list and the form in different pages,
we're using a library called react-router-dom.
react-router-dom is one of the React Router v4 child libraries
that only deal with DOM and browser routing. The way it works is fairly simple: you wrap the app in a Router
higher-order component and declare the routes via a Route component that will match its path to whatever is
in the browser and render the component passed to it.
yarn add react-router-dom@next
nano src/App.js...
import { BrowserRouter as Router, Route, Link } from 'react-router-dom';
...
import ContactCreate from './containers/ContactCreate';
...
render()
return (
<Router>
<div>
...
<div className="navbar-header">
<Link className="navbar-brand" to="/">React Apz</Link>
</div>
...
<section className="container-fluid">
<h2>Contacts Manager</h2>
<div className="container">
<Route exact path="/" component={ContactList} />
<Route path="/new" component={ContactCreate} />
</div>
</section>
</div>
</Router>
);
...Refresh, then try accessing http://localhost:3000, then http://localhost:3000/new. You'll see the list rendered
when accessing the first URL, then the form on the second. This is because of Route, which matches the history
path with the prop path, and, if it matches, the component will be rendered. On the root route, we passed
an exact prop whose value is implicitly true to make Route do a strict comparison, instead of a loose one.
Otherwise, ContactList would render alongside ContactCreate and any other component as long as the path
was a positive match for /.
We have also substituted the a tag on the app's navbar with a Link component imported from react-router-dom.
Link is just an a tag that is aware of the router that, when clicked, directs the user to the new route without
refreshing the app. This way, we will gain a lot of navigation speed by not having to download every single page
all the time.
Let's add a link to ContactList that leads to ContactCreate and vice-versa.
nano src/containers/ContactList.js...
import { Link, withRouter } from 'react-router-dom';
...
<h1>Contacts</h1>
<Link to="/new" className="btn btn-primary">
Create Contact
</Link>
...
export default connect(mapStateToProps, mapDispatchToProps)(withRouter(ContactList));nano src/containers/ContactForm.js...
import { Link } from 'react-router-dom';
...
<button type="submit" className="btn btn-primary" disabled={pristine || submitting}>Submit</button>
<button type="button" className="btn btn-default" onClick={reset} disabled={pristine || submitting}>Reset</button>
<Link to="/"><i className="glyphicon glyphicon-chevron-left"></i> Back to Home Page</Link>
...nano src/containers/ContactCreate.js...
import { withRouter } from 'react-router-dom';
...
export default connect(null, mapDispatchToProps)(withRouter(ContactCreate));The withRouter function wraps the component into a higher-order component that makes it aware of the router
props, such as history, pathname, parameters and methods to alter the browser history. This will be useful when
we need to redirect the user to a different page after doing something.
Since we want the user to return to the home page when he inserts a new contact, let's redirect them into handleSubmit.
nano src/containers/ContactCreate.js...
handleSubmit({ name, phone, email }) {
const { onSubmit, push } = this.props;
onSubmit({ name, phone, email });
push("/");
}
...Try adding a few contacts to the list before heading to the next step.
Next step: Delete a Contact