Change `children` prop from react-router to only be a Element type

Judging by
https://github.com/rackt/react-router/blob/master/docs/API.md#children-1
and a few inspections in the code, as well as tests, the `children`
prop injected into routes can only ever be a single React Element
object.

This allows us to easily get the active route of a child (if there is
an active route) by querying the `children`’s route prop.
This commit is contained in:
Brett Sun 2016-02-01 14:48:44 +01:00
parent 83012200d1
commit 764f81925b
6 changed files with 34 additions and 40 deletions

View File

@ -15,14 +15,10 @@ export default function AppBase(App) {
displayName: 'AppBase',
propTypes: {
children: React.PropTypes.element.isRequired,
history: React.PropTypes.object.isRequired,
location: React.PropTypes.object.isRequired,
routes: React.PropTypes.arrayOf(React.PropTypes.object).isRequired,
children: React.PropTypes.oneOfType([
React.PropTypes.arrayOf(React.PropTypes.element),
React.PropTypes.element
])
routes: React.PropTypes.arrayOf(React.PropTypes.object).isRequired
},
mixins: [History],
@ -42,10 +38,20 @@ export default function AppBase(App) {
},
render() {
const { children } = this.props;
// Get the currently active route of the app by using the injected route parameter
// on the currently active child route.
// Note that despite its name, this.props.children can only ever be a single
// React.PropTypes.element.
const activeRoute = children.props.route;
return (
<div>
<App {...this.props} />
<Footer />
<App
{...this.props}
activeRoute={activeRoute} />
<GlobalNotification />
<div id="modal" className="container" />
</div>

View File

@ -8,16 +8,13 @@ import Header from './header';
let AscribeApp = React.createClass({
propTypes: {
routes: React.PropTypes.arrayOf(React.PropTypes.object).isRequired,
children: React.PropTypes.oneOfType([
React.PropTypes.arrayOf(React.PropTypes.element),
React.PropTypes.element
])
activeRoute: React.PropTypes.object.isRequired,
children: React.PropTypes.element.isRequired,
routes: React.PropTypes.arrayOf(React.PropTypes.object).isRequired
},
render() {
const { children, routes } = this.props;
const { activeRoute, children, routes } = this.props;
return (
<div className="ascribe-default-app">

View File

@ -19,13 +19,10 @@ import { getCookie } from '../../../../utils/fetch_api_utils';
let PRApp = React.createClass({
propTypes: {
activeRoute: React.PropTypes.object.isRequired,
children: React.PropTypes.element.isRequired,
history: React.PropTypes.object.isRequired,
routes: React.PropTypes.arrayOf(React.PropTypes.object).isRequired,
children: React.PropTypes.oneOfType([
React.PropTypes.arrayOf(React.PropTypes.element),
React.PropTypes.element
])
routes: React.PropTypes.arrayOf(React.PropTypes.object).isRequired
},
getInitialState() {
@ -60,7 +57,7 @@ let PRApp = React.createClass({
render() {
const { children, history, routes } = this.props;
const { activeRoute, children, history, routes } = this.props;
const { currentUser } = this.state;
const subdomain = getSubdomain();

View File

@ -13,17 +13,14 @@ import { getSubdomain } from '../../../../utils/general_utils';
let PrizeApp = React.createClass({
propTypes: {
activeRoute: React.PropTypes.object.isRequired,
children: React.PropTypes.element.isRequired,
history: React.PropTypes.object.isRequired,
routes: React.PropTypes.arrayOf(React.PropTypes.object).isRequired,
children: React.PropTypes.oneOfType([
React.PropTypes.arrayOf(React.PropTypes.element),
React.PropTypes.element
])
routes: React.PropTypes.arrayOf(React.PropTypes.object).isRequired
},
render() {
const { children, history, routes } = this.props;
const { activeRoute, children, history, routes } = this.props;
const subdomain = getSubdomain();
// The second element of routes is always the active component object, where we can

View File

@ -11,17 +11,14 @@ import { getSubdomain } from '../../../utils/general_utils';
let WalletApp = React.createClass({
propTypes: {
activeRoute: React.PropTypes.object.isRequired,
children: React.PropTypes.element.isRequired,
history: React.PropTypes.object.isRequired,
routes: React.PropTypes.arrayOf(React.PropTypes.object).isRequired,
children: React.PropTypes.oneOfType([
React.PropTypes.arrayOf(React.PropTypes.element),
React.PropTypes.element
])
routes: React.PropTypes.arrayOf(React.PropTypes.object).isRequired
},
render() {
const { children, history, routes } = this.props;
const { activeRoute, children, history, routes } = this.props;
const subdomain = getSubdomain();
// The second element of routes is always the active component object, where we can

View File

@ -6,7 +6,7 @@ import { Route } from 'react-router';
import getPrizeRoutes from './components/whitelabel/prize/prize_routes';
import getWalletRoutes from './components/whitelabel/wallet/wallet_routes';
import App from './components/ascribe_app';
import AscribeApp from './components/ascribe_app';
import PieceList from './components/piece_list';
import PieceContainer from './components/ascribe_detail/piece_container';
@ -29,14 +29,14 @@ import { ProxyHandler, AuthRedirect } from './components/ascribe_routes/proxy_ha
const COMMON_ROUTES = (
<Route path='/' component={App}>
<Route path='/' component={AscribeApp}>
<Route
path='login'
component={ProxyHandler(AuthRedirect({to: '/collection', when: 'loggedIn'}))(LoginContainer)} />
<Route
path='register_piece'
component={ProxyHandler(AuthRedirect({to: '/login', when: 'loggedOut'}))(RegisterPiece)}
headerTitle='+ NEW WORK'/>
headerTitle='+ NEW WORK' />
<Route
path='collection'
component={ProxyHandler(AuthRedirect({to: '/login', when: 'loggedOut'}))(PieceList)}
@ -55,10 +55,10 @@ const COMMON_ROUTES = (
component={ProxyHandler(AuthRedirect({to: '/collection', when: 'loggedIn'}))(PasswordResetContainer)} />
<Route
path='settings'
component={ProxyHandler(AuthRedirect({to: '/login', when: 'loggedOut'}))(SettingsContainer)}/>
component={ProxyHandler(AuthRedirect({to: '/login', when: 'loggedOut'}))(SettingsContainer)} />
<Route
path='contract_settings'
component={ProxyHandler(AuthRedirect({to: '/login', when: 'loggedOut'}))(ContractSettings)}/>
component={ProxyHandler(AuthRedirect({to: '/login', when: 'loggedOut'}))(ContractSettings)} />
<Route path='coa_verify' component={CoaVerifyContainer} />
<Route path='*' component={ErrorNotFoundPage} />
</Route>