Skip to main content

Kea 2.6: Last 2.x release

ยท 2 min read
Marius Andra

Kea 2.6 will be the last 2.x of Kea. Version 3.0 is just around the corner with big changes, and version 2.6 is here to provide a smoother upgrade path.

  • Update version requirements of peer dependencies: reselect 4.1+, redux 4.2+, react-redux 7+ and react 16.8+. If you're using React 18, upgrade react-redux to version 8+.

  • React 18 support: Add a "redux listener silencing store enhancer", which prevents Redux's useSelectors from updating, when mounting a logic from within the body of a React component (e.g. with useValues). This effectively silences log spam in React 18 (Warning: Cannot update a component (Y) while rendering a different component (X). To locate the bad setState() call inside X, follow the stack trace as described.), and improves performance.

  • Support custom selector memoization. Use memoizeOptions as the 4th selector array value, which is then passed directly to reselect:

const logic = kea({
selectors: {
widgetKeys: [
(selectors) => [selectors.widgets],
(widgets) => Object.keys(widgets),
null, // PropTypes, will be removed in Kea 3.0
{ resultEqualityCheck: deepEqual },
],
},
})
  • Set the autoConnectMountWarning option to true by default. Kea 2.0 introduced "auto-connect", and while it works great in reducers and selectors, automatically connecting logic in listeners turned out to be a bad idea. Thus, in Kea 2.6, when accessing values on an unmounted logic, you'll get a warning by default. In Kea 3.0, it will trigger an error.
import { kea } from 'kea'
import { otherLogic } from './otherLogic'
import { yetAnotherLogic } from './yetAnotherLogic'

const logic = kea({
// connect: [otherLogic], // should have been explicitly connected like this, or mounted outside the logic
actions: { doSomething: true },
listeners: {
doSomething: () => {
// This will now print a warning if `otherLogic` is not mounted.
// Either add it to "connect" or make sure it's mounted elsewhere.
console.log(otherLogic.values.situation)
},
},
reducers: {
something: [
null,
{
// This `yetAnotherLogic` will still get connected automatically, not print a warning,
// and not require `connect`. That's because it's connected directly at build time, whereas
// in the listener, we're running within an asynchronous callback coming from who knows where.
// While this works, it's still good practice to explicitly define your dependencies.
[yetAnotherLogic.actionTypes.loadSessions]: () => 'yes',
},
],
},
})

Questions & Answers