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

Migrating existing Redux applications

Since kea is just redux, it is very easy to connect it to an existing redux application.

Reading non-Kea state

You may pull in data from any part of the Redux tree with the Kea through kea({ connect: { ... } }).

Instead of passing a logic to fetch from, pass a selector:

import { connect } from 'kea'

import someLogic from './some-logic'

const railsContext = (state) => state.rails

const logic = kea({
  connect: {
    values: [
      someLogic, [ // <----- instead of logic like this
        'prop1',
        'prop2'
      ],
      state => state.rails, [ // <----- pass a selector
        'i18nLocale',
        'currentUserId'
      ],
      state => state.form.myForm, [
        '* as myForm' // get everything as 'myForm'
      ]
    ]
  }

  // ...
})

Using non-Kea actions

Similarly, use an object of action creators and select the ones you need:

import { connect } from 'kea'

import someLogic from './some-logic'

const railsContext = (state) => state.rails

const actionsCreators = {
  doSomething: () => ({ type: 'DO_SOMETHING', payload: { } }),
  otherAction: ({ id }) => ({ type: 'OTHER_ACTION', payload: { id } }),
}

const logic = kea({
  connect: {
    actions: [
      someLogic, [ // <--------------- instead of logic like this
        'action1',
        'action2'
      ],
      actionsCreators, [ // <-- pass an object of action creators
        'doSomething', // <------------ and select what is needed
        'otherAction'
      ]
    ]
  }

  // ..
})

You may listen to other actions and either have them influence your reducers or run a saga when they happen. Just replace actions.something with ACTION_TYPE_CONSTANT, like so:

import { kea } from 'kea'

import { LOCATION_CHANGE } from 'react-router-redux'
import { SOME_ACTION } from './actions'

const logic = kea({
  actions: () => ({
    doit: true
  }),

  reducers: ({ actions }) => ({
    myValue: [false, {
      [SOME_ACTION]: () => false,
      [actions.doit]: () => true
    }]
  }),

  listeners: () => ({
    [LOCATION_CHANGE]: (payload) => {
      // ...
    }
  })
})

Using Kea actions and selectors elsewhere

If the redux-only part of your app needs access to some values or actions from kea logic stores, you can import them like so:

const logic = kea({
  actions: () => ({
    addOne: true
  }),
  reducers: ({ actions }) => ({
    myNumber: [0, {
      [actions.addOne]: (state) => state + 1
    }]
  }),
  selectors: ({ selectors }) => ({
    myNumberDouble: [
      () => [selectors.myNumber],
      (myNumber) => myNumber * 2
    ]
  })
})

// The logic must be mounted before you can access its fields
// This is done automatically when a React component is using it.

// If you're using Kea outside React, call logic.mount() manually to have
// access to all the fields below.
logic.mount()

// Call an action to add something
logic.actions.addOne()

// Create an action (returns the object { type: 'add one ...', payload: {} })
logic.actionCreators.addOne()

// Reselect selectors for querying redux (state defaults to getState())
logic.selectors.myNumber(state)
logic.selectors.myNumberDouble(state)

// Shorthand for selectors (implemented as getters)
logic.values.myNumber
logic.values.myNumberDouble

The API docs describe what is available to import.