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+ andreact
16.8+. If you're using React 18, upgradereact-redux
to version 8+.React 18 support: Add a "redux listener silencing store enhancer", which prevents Redux's
useSelector
s from updating, when mounting a logic from within the body of a React component (e.g. withuseValues
). 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 4thselector
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 totrue
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',
},
],
},
})