kea v2.6.0 Release Notes

Release Date: 2022-05-06 // almost 2 years ago
    • ⚡️ 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+.

    • ➕ 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 insideX, follow the stack trace as described.), and improves performance.

    • ⚠ 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.
          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',
          },
        ],
      },
    })
    
    • 👌 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 },
        ],
      },
    })