kea(options)
Create a new kea logic store and connect it to redux.
Usage
Here is a complete example with all the options available. See below for further explanations.
// scenes/my-random-scene/logic.js
import { kea } from 'kea'
import localStoragePlugin from 'kea-localstorage'
import otherLogic from './other-logic.js'
import dynamicLogic from './dynamic-logic.js'
export default kea({
plugins: [
localStoragePlugin
],
connect: {
actions: [
otherLogic, [
'firstAction',
'secondAction as renamedAction'
]
],
props: [
otherLogic, [
'firstProp',
'secondProp as renamedProp',
'* as allProps'
],
// use Dynamic Logic
dynamicLogic.withKey(props => props.id), [
'dynamicProp as thatProp'
],
// select from any redux tree node
(state) => state.somethingThatResolvesToAnObject, [
'variable',
'otherVariable'
]
]
},
path: () => ['scenes', 'myRandomScene', 'index'],
constants: () => ['STRING', 'OTHER_STRING'],
actions: ({ path, constants }) => ({
actionWithStaticPayload: 'payload value',
anotherActionWithAStaticPayload: { thisIs: 'that' },
simpleAction: true,
actionWithDynamicPayload: (id) => ({ id }),
actionWithManyParameters: (id, message) => ({ id, message }),
actionWithObjectInput: ({ id, message }) => ({ id, message })
}),
reducers: ({ actions, path, constants }) => ({
reducerKey: [defaultValue, propType, /* with localStoragePlugin: { persist: true }, */ {
// operations
[actions.simpleAction]: (state, payload) => state + payload.value // return the new state,
[actions.complexAction]: (state, payload) => {
// do more things in the block
return state + payload.value
},
[actions.noStateUsed]: (_, payload) => payload.value,
[actions.setToTrue]: () => true,
[actions.clearSomething]: () => false,
"ANY_OTHER_ACTION_TYPE": (state, payload, meta) => 'do whatever you want'
}],
constantDefault: [constants.OTHER_STRING, PropTypes.string, {
[actions.clearSomething]: () => constants.STRING,
[actions.someOtherAction]: (_, payload) => payload.value
}]
}),
selectors: ({ path, constants, actions, selectors }) => ({
selectorName: [
() => [selectors.inputSelector1, selectors.inputSelector2],
(input1, input2) => createOutput(input),
returnPropType
],
computedValue: [
() => [selectors.reducerKey, selectors.constantDefault],
(reducerKey, constantDefault) => {
return complicatedOperation(reducerKey, constantDefault)
},
PropTypes.object
]
})
})
// index.js
import myRandomSceneLogic from 'scenes/my-random-scene/logic'
Options
plugins: []
Plugins that only this logic store will use. See the plugins
array in getStore
on how to install global plugins.
// Input
plugins: [
localStoragePlugin
]
path: () => []
Give a name to the logic store and register it in a certain location in your application's Redux tree.
// Input
path: () => ['scenes', 'myRandomScene', 'logicMountPoint']
// Output
myRandomSceneLogic.path == ['scenes', 'myRandomScene', 'logicMountPoint']
constants: () => []
Create constants that can be used in other parts of the logic store.
// Input
constants: () => ['STRING', 'OTHER_STRING']
// Output
myRandomSceneLogic.constants == { STRING: 'STRING', OTHER_STRING: 'OTHER_STRING' }
actions: ({ path, constants }) => ({})
Define action creators
// Input
actions: ({ path, constants }) => ({
actionWithStaticPayload: 'payload value',
anotherActionWithAStaticPayload: { thisIs: 'that' },
simpleAction: true,
actionWithDynamicPayload: (id) => ({ id }),
actionWithManyParameters: (id, message) => ({ id, message }),
actionWithObjectInput: ({ id, message }) => ({ id, message })
})
// Output
myRandomSceneLogic.actions == {
actionWithStaticPayload: () => ({ type: '...', payload: { value: 'payload value' } }),
anotherActionWithAStaticPayload: () => ({ type: '...', payload: { thisIs: 'that' } }),
simpleAction: () => ({ type: '...', payload: { value: true } }),
actionWithDynamicPayload: (id) => ({ type: '...', payload: { id } }),
actionWithManyParameters: (id, message) => ({ type: '...', payload: { id, message } }),
actionWithObjectInput: ({ id, message }) => ({ type: '...', payload: { id, message } })
}
reducers: ({ path, constants, actions }) => ({})
Define the structure and logic of your reducers
// Input
reducers: ({ actions, path, constants }) => ({
reducerKey: [defaultValue, propType, /* optional options: { persist: true }, */ {
// operations
[actions.simpleAction]: (state, payload) => state + payload // return the new state,
[actions.complexAction]: (state, payload) => {
// do more things in the block
return state + payload
},
[actions.noStateUsed]: (_, payload) => payload.value,
[actions.setToTrue]: () => true,
[actions.clearSomething]: () => false,
"ANY_OTHER_ACTION_TYPE": (state, payload, meta) => 'do whatever you want'
}],
constantDefault: [constants.OTHER_STRING, PropTypes.string, {
[actions.clearSomething]: () => constants.STRING,
[actions.someOtherAction]: (_, payload) => payload.value
}]
})
// Output
myRandomSceneLogic.reducers == {
reducerKey: (initialState = defaultValue, action) => /* ... */,
constantDefault: (initialState = constants.OTHER_STRING, action) => /* ... */,
}
myRandomSceneLogic.reducer == combineReducers(reducers)
selectors: ({ path, constants, actions, selectors }) => ({})
Define selectors, which are only recomputed when their input changes
// Input
selectors: ({ path, constants, actions, selectors }) => ({
selectorName: [
() => [selectors.inputSelector1, selectors.inputSelector2],
(input1, input2) => createOutput(input),
returnPropType
],
computedValue: [
() => [selectors.reducerKey, selectors.constantDefault],
(reducerKey, constantDefault) => {
return complicatedOperation(reducerKey, constantDefault)
},
PropTypes.object
]
})
// Output
myRandomSceneLogic.selectors == {
// all reducer keys first,
reducerKey: (state) => state.scenes.myRandomScene.index.reducerKey,
constantDefault: (state) => state.scenes.myRandomScene.index.constantDefault,
// other defined selectors
selectorName: (state) => memoizedSelectorForSelectorName(state),
computedValue: (state) => memoizedSelectorForComputedValue(state)
}
myRandomSceneLogic.selector == (state) => ({
reducerKey: state.scenes.myRandomScene.index.reducerKey,
constantDefault: state.scenes.myRandomScene.index.constantDefault,
selectorName: memoizedSelectorForSelectorName(state),
computedValue: memoizedSelectorForComputedValue(state)
})
connect: {}
Fetch actions and selectors/props from other logic stores.
// Input
connect: {
actions: [
otherLogic, [
'firstAction',
'secondAction as renamedAction'
]
],
props: [
otherLogic, [
'firstProp',
'secondProp as renamedProp',
'* as allProps'
],
// use Dynamic Logic
dynamicLogic.withKey(props => props.id), [
'dynamicProp as thatProp'
],
// select from any redux tree node
(state) => state.somethingThatResolvesToAnObject, [
'variable',
'otherVariable'
]
]
}
// Output
myRandomSceneLogic.actions == {
firstAction: otherLogic.actions.firstAction,
renamedAction: otherLogic.actions.secondAction
}
myRandomSceneLogic.selectors == {
firstProp: otherLogic.selectors.firstProp,
renamedProp: otherLogic.selectors.secondProp,
allProps: otherLogic.selector,
variable: state.somethingThatResolvesToAnObject.variable,
otherVariable: state.somethingThatResolvesToAnObject.otherVariable
}