props
Props
When you build a logic
, you can pass it an object that will be stored as props
:
const props = { id: 10 }
const logic = kea([])
logic(props).props === props
logic.build(props).props === props
Calling logic(props)
or logic.build(props)
is a fast operation.
In case the logic is already mounted, its props
will be updated to the new passed props.
Props are merged
When you build logic with multiple props, they get merged.
// logic keyed on id
type LogicProps = {
id: number
username?: string
defaultRecord?: string
}
const logic = kea([
props({} as LogicProps),
key((props) => props.id),
actions({ doSomething: true }),
])
// mount once with one set of props
logic({ id: 1, username: 'keajs', defaultRecord: 'something' }).mount()
// call with another set of props
logic({ id: 1, defaultRecord: 'new' }).actions.doSomething()
// props are always merged, never overridden
logic({ id: 1 }).props === { id: 1, username: 'keajs', defaultRecord: 'new' }
Pass data from React
You can pass random data from React onto the logic via props
. For example various defaults:
function FancyPantsCounter() {
const builtLogic = counterLogic({
defaultCounter: 1000,
onChange: (c) => console.log(c),
})
const { counter } = useValues(builtLogic)
// ...
}
const counterLogic = kea([
actions({
increment: (amount) => ({ amount }),
decrement: (amount) => ({ amount }),
}),
reducers(({ props }) => ({
counter: [
props.defaultCounter || 0,
{
increment: (state, { amount }) => state + amount,
decrement: (state, { amount }) => state - amount,
},
],
})),
listeners(({ props, values }) => ({
increment: ({ amount }) => {
console.log(`incrementing by ${amount}`)
console.log(`default ${props.defaultCounter || 0}`)
props.onChange?.(values.counter)
},
})),
])
Typed Props
When using kea-typegen, you may pass a type to the props
builder:
import { kea, props } from 'kea'
import { logicType } from './logicType'
interface LogicProps {
id: number
}
const logic = kea<logicType<LogicProps>>([
// specify the type here
props({} as LogicProps),
])
Detect Changes
You may use the propsChanged
event to detect when props changed:
import { kea, props } from 'kea'
import { logicType } from './logicType'
interface LogicProps {
id: number
}
const logic = kea<logicType<LogicProps>>([
props({} as LogicProps),
propsChanged(({ actions, props }, oldProps) => {
console.log({ props, oldProps })
}),
])
Sync props
from React
Here's a sample TextField
that syncs props
with React, and translates those to its actions
and values
.
This example is over-engineered, but serves as a practical example if you need to build a controlled React component, and want to power it with a logic.
import React from 'react'
import { kea, actions, reducers, listeners, props, propsChanged, path, useValues, useActions } from 'kea'
import type { textFieldLogicType } from './TextFieldType'
interface TextFieldLogicProps {
value: string
onChange?: (value: string) => void
}
const textFieldLogic = kea<textFieldLogicType<TextFieldLogicProps>>([
props({ value: '', onChange: undefined } as TextFieldLogicProps),
actions({ setValue: (value: string) => ({ value }) }),
reducers(({ props }) => ({ value: [props.value, { setValue: (_, { value }) => value }] })),
listeners(({ props }) => ({ setValue: ({ value }) => props.onChange?.(value) })),
propsChanged(({ actions, props }, oldProps) => {
if (props.value !== oldProps.value) {
actions.setValue(props.value)
}
}),
])
export function TextField(props: TextFieldLogicProps) {
const { value } = useValues(textFieldLogic(props))
const { setValue } = useActions(textFieldLogic(props))
return <input value={value} onChange={(e) => setValue(e.target.value)} />
}
Questions & Answers
Ask questions about this page here.