This documentation is for the old Kea 0.28. To see the latest docs, click here!

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.