Skip to main content

Kea 2.3: Bind Logic

ยท 2 min read
Marius Andra
TL;DR

New tag: <BindLogic logic={itemLogic} props={{ id: 12 }}>. It lets you write useValues(itemLogic) instead of useValues(itemLogic({ id: 12 })) in nested children. Powered by React Context.

When using keyed logics it's easy to get into a situation where you need to pass props similar to this:

import { kea, useValues } from 'kea'

const itemLogic = kea({ key: (props) => props.id /* ... */ })

function List() {
return (
<>
<Item id={12} />
<Item id={15} />
</>
)
}

function Item({ id }) {
const { className } = useValues(itemLogic({ id }))

return (
<div className={className}>
<Title id={id} />
<Body id={id} />
</div>
)
}

function Title({ id }) {
const { title, url } = useValues(itemLogic({ id }))
return <a href={url}>{title}</a>
}

function Body({ id }) {
const { body } = useValues(itemLogic({ id }))
return <div>{body}</div>
}

In Kea 2.3 you can use <BindLogic> to clear this up:

import { kea, useValues, BindLogic } from 'kea'

const itemLogic = kea({ key: (props) => props.id /* ... */ })

function List() {
return (
<>
<BindLogic logic={itemLogic} props={{ id: 12 }}>
<Item />
</BindLogic>
<BindLogic logic={itemLogic} props={{ id: 15 }}>
<Item />
</BindLogic>
</>
)
}

function Item() {
const { className } = useValues(itemLogic)

return (
<div className={className}>
<Title />
<Body />
</div>
)
}

function Title() {
const { title, url } = useValues(itemLogic)
return <a href={url}>{title}</a>
}

function Body() {
const { body } = useValues(itemLogic)
return <div>{body}</div>
}

When you write <BindLogic logic={itemLogic} props={{ id: 12 }}>, Kea stores a specific build of itemLogic inside a React Context. Any nested children will get that when calling e.g: useValues(itemLogic).

Questions & Answers