Skip to content

Commit 795592f

Browse files
committed
docs: add instructions for using with React Router
1 parent 26aeadd commit 795592f

File tree

2 files changed

+93
-2
lines changed

2 files changed

+93
-2
lines changed

www/src/components/Layout.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ class Layout extends React.Component {
6969
<Navbar.Toggle />
7070
</Navbar.Header>
7171
<Navbar.Collapse>
72-
<Nav pullRight>
72+
<Nav pullLeft>
7373
{data.site.siteMetadata.componentPages.map(
7474
({ path, displayName }) => (
7575
<NavItem key={path} to={path} location={location}>
@@ -78,9 +78,14 @@ class Layout extends React.Component {
7878
)
7979
)}
8080
</Nav>
81+
<Nav pullRight>
82+
<NavItem to="/with-react-router" location={location}>
83+
With React Router
84+
</NavItem>
85+
</Nav>
8186
</Navbar.Collapse>
8287
</Navbar>
83-
<div style={{ paddingTop: '4rem', paddingBottom: '1rem' }}>
88+
<div style={{ paddingTop: '4rem', paddingBottom: '1.5rem' }}>
8489
{children}
8590
</div>
8691
</div>

www/src/pages/with-react-router.js

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import { graphql } from 'gatsby';
2+
import PropTypes from 'prop-types';
3+
import React from 'react';
4+
import { Grid } from 'react-bootstrap';
5+
import Layout from '../components/Layout';
6+
import Example from '../components/Example';
7+
8+
const propTypes = {
9+
location: PropTypes.object.isRequired,
10+
data: PropTypes.shape({
11+
site: PropTypes.shape({
12+
siteMetadata: PropTypes.shape({
13+
componentPages: PropTypes.arrayOf(
14+
PropTypes.shape({
15+
path: PropTypes.string.isRequired,
16+
displayName: PropTypes.string.isRequired,
17+
})
18+
).isRequired,
19+
}).isRequired,
20+
}).isRequired,
21+
}).isRequired,
22+
};
23+
24+
const WithReactRouter = ({ data, location }) => (
25+
<Layout data={data} location={location}>
26+
<Grid>
27+
<h1>Usage with React Router</h1>
28+
<p>
29+
People often want to animate route transitions, which can result in
30+
delightful UX when used in moderation. The first instict might be to use
31+
wrap all routes in <code>TransitionGroup</code>, but that approach
32+
requires hacks and falls apart easily when used with trickier components
33+
of React Router like <code>Redirect</code>. You should use{' '}
34+
<code>CSSTransition</code> for each route and manage their{' '}
35+
<code>in</code> prop on their own.
36+
</p>
37+
<p>
38+
The main challenge is the <strong>exit</strong> transition because React
39+
Router changes to a new route instantly, so we need to keep the old
40+
route around long enough to transition out of it. Fortunately,{' '}
41+
<code>Route</code>'s <code>children</code> prop also accepts a{' '}
42+
<em>function</em>, which should not be confused with the{' '}
43+
<code>render</code> prop! Unlike the <code>render</code> prop,{' '}
44+
<code>children</code> function runs whether the route is matched or not.
45+
React Router passes the object containing a <code>match</code> object,
46+
which exists if the route matches, otherwise it's <code>null</code>.
47+
This enables us to manage the <code>in</code> prop of{' '}
48+
<code>CSSTransition</code> based on the presence of <code>match</code>.
49+
</p>
50+
<p>
51+
Exit transitions will cause the content of routes to linger until they
52+
disappear, which might pose some styling challenges. Make sure that
53+
routes don't affect each other's layout, for example you can remove them
54+
from the flow of the document by using absolute or fixed positioning.
55+
</p>
56+
<blockquote>
57+
<p>
58+
<b>Note</b>: When using React Transition Group with React Router, make
59+
sure to avoid using the <code>Switch</code> component because it only
60+
executes the first matching <code>Route</code>. This would make the
61+
exit transition impossible to achieve because the exiting route will
62+
no longer match the current URL and the <code>children</code> function
63+
won't execute.
64+
</p>
65+
</blockquote>
66+
</Grid>
67+
<Example
68+
codeSandbox={{
69+
title: 'CSSTransition + React Router',
70+
id: '38qm5m0mz1',
71+
}}
72+
/>
73+
</Layout>
74+
);
75+
76+
WithReactRouter.propTypes = propTypes;
77+
78+
export default WithReactRouter;
79+
80+
export const pageQuery = graphql`
81+
query WithReactRouterQuery {
82+
site {
83+
...Layout_site
84+
}
85+
}
86+
`;

0 commit comments

Comments
 (0)