A common pattern on Facebook and other applications is to show pictures in a gallery, this gallery may be an interactive modal. However if the user visits the page from just a URL you might want to display the gallery outside of the modal. React Router makes this simpler by allowing you to pass in a state object when routing.
First off lets setup our routes, we'll have our base Home
route component. Then we'll also setup a Photo
component. This will render a div with a random image in it.
const Home = () => <div>You're on the Home Tab</div>; const Photo = () => { return ( <div> <div> <img src="https://source.unsplash.com/random" /> </div> </div> ); };
Now we need to setup our app routes and also be able to navigate between them. We have 2 links, and then 2 routes. Our /
route for Home
needs the exact
prop otherwise it will render even when we visit the /photo
route.
class App extends Component { render() { return ( <div> <div className="links"> <Link to="/" className="link"> Home </Link> <Link to="/photo" className="link"> View Photo </Link> </div> <div className="tabs"> <Switch> <Route path="/" exact component={Home} /> <Route path="/photo" component={Photo} /> </Switch> </div> </div> ); } }
Rather than just passing in a simple string to Link
you can pass in an object. This will be accessible in the location
prop that is passed into the component rendered on our <Route>
.
We'll add in {modal: true}
because if the user clicks on it they are active in the application and so we know it's not a fresh visit from someone just visiting a URL.
<Link to={{ pathname: "/photo", state: { modal: true }, }} className="link" > View Photo </Link>
Now we need to adjust our Photo
route component to respond when we indicate we want a modal. We destructure location
from our props that are passed in. We default state
to an empty {}
because in the event that state isn't set it will just be undefined.
Then we grab our modal
value off of state.
const Photo = ({ location }) => { const { state = {} } = location; const { modal } = state; return ( <div> <div> <img src="https://source.unsplash.com/random" /> </div> </div> ); };
Now with our knowledge of whether or not we are going to render a modal
we can make adjustments. For example we add a modal
className
to our outer div. We also render a Close
button that is just a link to the home route which will render a different route, thus causing the modal to close.
const Photo = ({ location }) => { const { state = {} } = location; const { modal } = state; return ( <div className={modal ? "modal" : undefined}> {modal && <Link to="/">Close</Link>} <div> <img src="https://source.unsplash.com/random" /> </div> </div> ); };
Passing state is an effective method to change the experience for users as they flow through your application while altering the experience for users that visit your application from a direct URL. Both experiences should be relatively identical as to not confuse the user from visit to visit, but route state should be used to enhance the users experience.