0

i have routes that look like this:

<Router history={syncHistoryWithStore(browserHistory, store)}>
  <Route path='/' component={Widget}>
    <Route path='/a' component={A} />
    <Route path='/b' component={B} expand />
    <Route path='/c' component={C} />
  </Route>
  <Route path='*' component={FourOhFour} />
</Router>

so, Widget renders A, B, or C as children. Note that on B i've added my own prop, expand. usually, Widget wraps children in some other padded DOM node. when expand is truthy, i do not want it to be wrapped, and can handle it accordingly. how can i go about achieving this goal?

  • in my Widget component, props.routes is a thing, but it contains an array of each route in the tree.
  • in my Widget component, props.route is a thing, but it doesn't give me a reference to the matched child route.
    • its like i want a props.route.child, in order to sniff for expand

i envisioned something like this:

render () {
  const { children, route: { child: { expand } } } = this.props
  return (
    <div {...someOtherProps}>
      {expand ? children : <p id="padded-thing">{children}</p>}
    </div>
  )
}

i'm confident that this is a solved problem, albeit perhaps my strategy is off.

i did see a couple of near dupe threads, like Passing additional parameters in React Router, but given that im asking about a parent route seeing a to-render-child-route, i figured this is different enough. thanks!

Community
  • 1
  • 1
cdaringe
  • 1,274
  • 2
  • 15
  • 33

1 Answers1

0

I think you might be approaching it in a bit of a wonky way. React is generally a top-down, without a whole lot of action going the other way. Generally when you want to communicate back up, you pass in a callback or something.

You mentioned you don't want it to be wrapped, but I think having a Wrapper component would be the cleanest approach by far.

Something like this:

import { A, B, C } from './children';
import { Wrapper } from './wrapper';

const WrappedB = <Wrapper><B /></Wrapper>;

// ...
<Router history={syncHistoryWithStore(browserHistory, store)}>
  <Route path='/' component={Widget}>
    <Route path='/a' component={A} />
    <Route path='/b' component={WrappedB} />
    <Route path='/c' component={C} />
  </Route>
  <Route path='*' component={FourOhFour} />
</Router>

This let's you keep the top-down methodology without having to do some awkward parent-looks-at-child-then-renders-child-different approach.

samanime
  • 25,408
  • 15
  • 90
  • 139
  • doh! i submitted my remark early, thinking SO let me do snippets in comments. anyway, i updated my original post w/ how i had actually envisioned it, still top down. i think your approach is probably sufficient for me. thx :) i would, however, like to figure out a way to do that wrapping from within `Widget` vs at the route level – cdaringe May 02 '17 at 20:30