As far as I can tell there is no way to get the router to add a unique key to the components that are rendered for a given route. This makes it impossible to use CSSTransitionGroup to wrap {this.props.children} to achieve animations between routes since the child component has no key and can't be distinguished from any other component by the transition group. Am I missing something. I've read the source and found no way to do this.
Happy to submit a PR to allow for the setting of a key, but want to make sure I'm not missing something first.
Found a way to do this by the way. You can specify a custom createElement function and pass it to the Router like so:
const createElement = (Component, props) => {
return <Component key={`${props.route.name}RouteComponent`} {...props}/>
}
<Router children={routes} createElement={createElement} />
or in your normal render method <div>{React.cloneElement(this.props.children, { key: 'some key' })}</div>
@mhodgson here's a big THANK YOU! I only had to change props.route.name to props.route.path since .name was undefined in my case so all the keys were the same - that's it. So now i can do this:
<ReactTransitionGroup ...>{this.props.children}</ReactTransitionGroup>
which is AWESOME! instead of this:
<ReactTransitionGroup ...>
{React.cloneElement(this.props.children, { key: 'some key' })}
</ReactTransitionGroup>
I used to do the latter, like @ryanflorence said, and it works perfectly, but ONLY for 1-level deep route hierarchies (i.e. no nesting!). Once you have wrapper1 > wrapper2 > content, any navigation between child content components would redraw wrapper2 because of cloneElement, but no more!
YAY!
I found that adding a createElement Component obfuscated my intentions.
Instead, you can combine map and cloneElement right at the point of interest:
{ // Key children based on their route name
React.Children.map(children, (child) => {
return React.cloneElement(child, { key: child.props.route.path });
})
}
Most helpful comment
Found a way to do this by the way. You can specify a custom
createElementfunction and pass it to the Router like so: