Frequently Asked Questions
Got more questions to add? Think something belongs here? Raise an issue!
Using React-Router (V4) routes within kea connected components
If your kea component contains routes from react-router, they will not automatically receive changes to the current location that's passed implicitly by React context due to how React optimizes for rendering. This will cause React Router's location-aware components out of sync, as in the following example:
import React, { Component } from 'react'
import { kea } from 'kea'
const logic = kea({})
class _Wrapper extends Component {
render() {
return(
<div>{this.props.children}</div>
)
}
}
const Wrapper = logic(_Wrapper) // switch routes does not work
//const Wrapper = _Wrapper // switch routes works
const App = () => (
<ConnectedRouter history={history}>
<Wrapper>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/foo">Foo</Link></li>
<li><Link to="/bar">Bar</Link></li>
</ul>
<Route exact path="/" component={Home} />
<Route path="/foo" component={Foo} />
<Route path="/bar" component={Bar} />
</Wrapper>
</ConnectedRouter>
)
Quick Solution
The easiest solution is to wrap the kea component with the withRouter() to remove the blocked states. This is not the most efficient solution.
const Wrapper = withRouter(logic(_Wrapper))
Recommended Solution
The more efficient method is to pass the location explicitly as a prop to the kea component. Here's one approach:
const routeSelector = (state) => state.router
const logic = kea({
connect: {
props: [
routeSelector, [
'location'
]
]
},
// other kea properties (e.g. actions, reducers, etc)
})
class _Wrapper extends Component {
render() {
return(
<div>{this.props.children}</div>
)
}
}
const Wrapper = logic(_Wrapper) // this will now work
const App = () => (
<ConnectedRouter history={history}>
<Wrapper>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/foo">Foo</Link></li>
<li><Link to="/bar">Bar</Link></li>
</ul>
<Route exact path="/" component={Home} />
<Route path="/foo" component={Foo} />
<Route path="/bar" component={Bar} />
</Wrapper>
</ConnectedRouter>
)
The detailed description for how to do this can be found at Dealing with Update Blocking.