### Combined Kea Logic Example Source: https://github.com/keajs/kea/blob/master/_autodocs/api-reference/key-props-path.md Demonstrates a combined Kea logic setup including path, key, props, reducers, selectors, actions, and listeners. Use this for complex state management scenarios. ```typescript const todoLogic = kea([ // Define where this exists in the state tree and how to identify instances path(['scenes', 'todos']), key((props) => props.listId), props({ listId: 0 } as { listId: number }), // Define the data and how to modify it reducers({ todos: [[], { /* ... */ }], filter: ['all', { /* ... */ }], }), // Define computed values selectors({ filteredTodos: [ (s, p) => [s.todos, s.filter, p.listId], (todos, filter, listId) => { // filter todos... return todos } ], }), // Define actions actions({ addTodo: (title: string) => ({ title }), }), // Listen to actions listeners({ addTodo: ({ title }, breakpoint) => { console.log('Added:', title) }, }), ]) // Usage with props const list = todoLogic({ listId: 1 }) list.mount() ``` -------------------------------- ### afterMount() Usage Example Source: https://github.com/keajs/kea/blob/master/_autodocs/api-reference/defaults-events.md Demonstrates how to use the afterMount helper to execute logic after a Kea logic instance has been mounted. This example logs the logic's path and fetches data. ```typescript const dataLogic = kea([ afterMount((logic) => { console.log('Loading data for', logic.path) fetch('/api/data').then(r => r.json()).then(console.log) }), ]) ``` -------------------------------- ### Complete Kea Application Setup Source: https://github.com/keajs/kea/blob/master/_autodocs/api-reference/context.md Demonstrates a full application setup including context initialization with custom plugins and defaults, defining a logic with reducers and actions, mounting the logic, and accessing the global context. ```typescript import { resetContext, getContext, kea, actions, reducers } from 'kea' import customPlugin from './customPlugin' // Initialize context with options resetContext({ plugins: [customPlugin], debug: true, defaults: { app: { initialized: false, }, }, }) // Define a logic const appLogic = kea([ reducers({ initialized: [false, { initApp: () => true, }], }), actions({ initApp: () => null, }), ]) // Mount logic and use const logic = appLogic.build() logic.mount() // Access context const ctx = getContext() console.log(ctx.store.getState()) ``` -------------------------------- ### beforeUnmount() Usage Example Source: https://github.com/keajs/kea/blob/master/_autodocs/api-reference/defaults-events.md Demonstrates how to use the beforeUnmount helper to execute cleanup logic before a Kea logic instance is unmounted. This example logs a message and cancels pending requests. ```typescript const listLogic = kea([ beforeUnmount((logic) => { console.log('Cleaning up list') cancelPendingRequests() }), ]) ``` -------------------------------- ### Simple Listener Example Source: https://github.com/keajs/kea/blob/master/_autodocs/api-reference/listeners.md A basic example demonstrating how to define a listener for the `increment` action. This listener logs a message to the console when the action is dispatched. ```typescript const counterLogic = kea([ actions({ increment: () => null, }), listeners({ increment: ({ payload }, breakpoint) => { console.log('Count was incremented') }, }), ]) ``` -------------------------------- ### Complete Kea Logic Example in React Source: https://github.com/keajs/kea/blob/master/_autodocs/api-reference/react-hooks.md A full example demonstrating how to define Kea logic (actions, reducers, selectors, listeners) and integrate it into a React component using Kea's React hooks. ```typescript import { kea, actions, reducers, selectors, listeners } from 'kea' import { useValues, useActions, useAsyncActions } from 'kea' const todoLogic = kea([ actions({ addTodo: (title: string) => ({ title }), removeTodo: (id: number) => ({ id }), }), reducers({ todos: [[], { addTodo: (state, { title }) => [ ...state, { id: Date.now(), title, done: false } ], removeTodo: (state, { id }) => state.filter(todo => todo.id !== id), }], }), selectors({ todosCount: [(s) => [s.todos], (todos) => todos.length], }), listeners({ addTodo: ({ title }, breakpoint) => { console.log('Todo added:', title) }, }), ]) function TodoApp() { const { todos, todosCount } = todoLogic.useValues() const { addTodo, removeTodo } = todoLogic.useActions() const [input, setInput] = React.useState('') const handleAdd = () => { addTodo(input) setInput('') } return (
setInput(e.target.value)} />

Todos: {todosCount}

{todos.map(todo => (
{todo.title}
))}
) } export default todoLogic.wrap(TodoApp) ``` -------------------------------- ### Testing Configuration Source: https://github.com/keajs/kea/blob/master/_autodocs/configuration.md Set up Kea for testing environments, enabling store creation and applying test-specific defaults. Includes setup and teardown for contexts. ```typescript // Before each test resetContext({ createStore: true, defaults: { // test defaults }, }) // After each test closeContext() ``` -------------------------------- ### Complete Kea React Application Example Source: https://github.com/keajs/kea/blob/master/_autodocs/api-reference/react-components.md Demonstrates a full React application using Kea for state management. It includes defining logic with actions and reducers, and integrating it into components using useValues and useActions. ```typescript import React, { useState } from 'react' import { kea, actions, reducers, selectors } from 'kea' import { BindLogic, useValues, useActions } from 'kea' // Define a logic const postLogic = kea([ actions({ openPost: (id: number) => ({ id }), closePost: () => null, }), reducers({ openPostId: [null as number | null, { openPost: (_, { id }) => id, closePost: () => null, }], }), ]) // Component using the logic function PostDetail() { const { openPostId } = postLogic.useValues() const { closePost } = postLogic.useActions() if (!openPostId) return null return (

Post: {openPostId}

) } // Container component function PostsApp() { const [selectedId, setSelectedId] = useState(null) return (

Posts

) } export default PostsApp ``` -------------------------------- ### Selector Examples Source: https://github.com/keajs/kea/blob/master/_autodocs/api-reference/selectors.md Illustrates various ways to define and use selectors, including simple selectors, selectors with multiple inputs, selectors using props, connected selectors, custom memoization, complex computations, and selectors with conditional logic. ```APIDOC ## Examples ### Simple Selector ```typescript const counterLogic = kea([ reducers({ count: [0, { /* ... */ }], }), selectors({ doubleCount: [(s) => [s.count], (count) => count * 2], }), ]) // Usage const doubleCount = counterLogic.selectors.doubleCount(state) const value = counterLogic.values.doubleCount // inside React component ``` ### Multiple Inputs ```typescript const todoLogic = kea([ reducers({ todos: [[], { /* ... */ }], filter: ['all', { /* ... */ }], }), selectors({ filteredTodos: [ (s) => [s.todos, s.filter], (todos, filter) => { if (filter === 'done') { return todos.filter(t => t.done) } else if (filter === 'pending') { return todos.filter(t => !t.done) } return todos } ], todoCount: [(s) => [s.todos], (todos) => todos.length], completedCount: [(s) => [s.todos], (todos) => todos.filter(t => t.done).length], }), ]) ``` ### Using Props ```typescript const itemLogic = kea([ key((props) => props.id), props({ id: 0, multiplier: 1 } as { id: number, multiplier: number }), reducers({ count: [0, { /* ... */ }], }), selectors({ countMultiplied: [ (s, p) => [s.count, p.multiplier], (count, multiplier) => count * multiplier, ], }), ]) ``` ### Connected Selectors ```typescript const appLogic = kea([ connect({ values: [todoLogic, ['filteredTodos']], }), selectors({ todoMessage: [ (s) => [s.filteredTodos], (todos) => `You have ${todos.length} todos`, ], }), ]) ``` ### Custom Memoization ```typescript const expensiveLogic = kea([ reducers({ items: [[], { /* ... */ }], }), selectors({ computedItems: [ (s) => [s.items], (items) => { // expensive computation return items.map(item => ({ ...item, computed: heavyCalculation(item) })) }, { maxSize: 1 }, // memoization options ], }), ]) ``` ### Complex Computation ```typescript const analyticsLogic = kea([ reducers({ events: [[], { /* ... */ }], startDate: [null, { /* ... */ }], endDate: [null, { /* ... */ }], }), selectors({ filteredEvents: [ (s) => [s.events, s.startDate, s.endDate], (events, start, end) => events.filter(e => { const date = new Date(e.timestamp) return (!start || date >= start) && (!end || date <= end) }), ], eventStats: [ (s) => [s.filteredEvents], (events) => ({ total: events.length, byType: events.reduce((acc, e) => { acc[e.type] = (acc[e.type] || 0) + 1 return acc }, {}), }), ], }), ]) ``` ### Selector with Conditional Logic ```typescript const searchLogic = kea([ reducers({ query: ['', { /* ... */ }], results: [[], { /* ... */ }], }), selectors({ hasResults: [ (s) => [s.results, s.query], (results, query) => query.length > 0 && results.length > 0, ], displayResults: [ (s) => [s.results, s.query], (results, query) => query.length > 0 ? results : [], ], }), ]) ``` ``` -------------------------------- ### Combined Kea Logic with afterMount and beforeUnmount Source: https://github.com/keajs/kea/blob/master/_autodocs/api-reference/defaults-events.md An example showcasing the integration of afterMount and beforeUnmount helpers within a Kea logic definition, alongside reducers and actions. This snippet demonstrates setting up data fetching on mount and cleanup logic on unmount. ```typescript import { kea, reducers, actions, afterMount, beforeUnmount } from 'kea' const newsLogic = kea([ reducers({ articles: [[], { /* ... */ }], isLoading: [false, { /* ... */ }], }), actions({ setArticles: (articles: any[]) => ({ articles }), setLoading: (loading: boolean) => ({ loading }), }), afterMount(() => { newsLogic.actions.setLoading(true) fetch('/api/articles') .then(r => r.json()) .then(articles => newsLogic.actions.setArticles(articles)) .finally(() => newsLogic.actions.setLoading(false)) }), beforeUnmount(() => { // Cancel any pending requests }), ]) ``` -------------------------------- ### Debug Plugin Example Source: https://github.com/keajs/kea/blob/master/_autodocs/api-reference/store-plugins.md A Kea plugin that logs messages before and after logic is built, useful for debugging. ```typescript const debugPlugin: KeaPlugin = { name: 'debug', events: { beforeLogic(logic, input) { console.log(`Building ${logic.pathString}`) }, afterLogic(logic, input) { console.log(`Built ${logic.pathString}`, logic) }, }, } export default debugPlugin ``` -------------------------------- ### propsChanged() Usage Example Source: https://github.com/keajs/kea/blob/master/_autodocs/api-reference/defaults-events.md Demonstrates how to use the propsChanged helper to react to changes in a keyed logic's props. This example loads user data when the userId prop changes. ```typescript const userLogic = kea([ key((props) => props.userId), props({ userId: 0 } as { userId: number }), propsChanged((logic, oldProps) => { if (logic.props.userId !== oldProps.userId) { loadUser(logic.props.userId) } }), ]) ``` -------------------------------- ### Using Selectors in React Components Source: https://github.com/keajs/kea/blob/master/_autodocs/api-reference/selectors.md Demonstrates how to use selectors within a React component using `useValues` to get selector values and `useActions` to get action creators. This example shows fetching and displaying filtered todos. ```typescript function TodoList() { const { filteredTodos, filter } = todoLogic.useValues() const { setFilter } = todoLogic.useActions() return ( <>

Showing {filter} items: {filteredTodos.length}

{filteredTodos.map(todo => (
{todo.title}
))} ) } ``` -------------------------------- ### Listener with Connected Actions Source: https://github.com/keajs/kea/blob/master/_autodocs/api-reference/listeners.md This example shows a listener for the `setUser` action that is connected from another logic (`userLogic`). When `setUser` is dispatched in `userLogic`, this listener in `notificationLogic` is triggered, displaying a notification. ```typescript const notificationLogic = kea([ connect({ actions: [userLogic, ['setUser']], }), listeners({ setUser: ({ user }, breakpoint) => { console.log('User changed:', user.name) showNotification(`Welcome ${user.name}`) }, }), ]) ``` -------------------------------- ### Analytics Plugin Example Source: https://github.com/keajs/kea/blob/master/_autodocs/api-reference/store-plugins.md A Kea plugin that tracks logic mounting and unmounting events using an analytics service. ```typescript const analyticsPlugin: KeaPlugin = { name: 'analytics', events: { afterMount(logic) { analytics.track('logic_mounted', { path: logic.pathString, }) }, afterUnmount(logic) { analytics.track('logic_unmounted', { path: logic.pathString, }) }, }, } export default analyticsPlugin ``` -------------------------------- ### Wrapping a React Component with Kea Logic Source: https://github.com/keajs/kea/blob/master/_autodocs/api-reference/kea.md A concise example of wrapping a simple React component (`MyComponent`) with `counterLogic`. The logic is automatically mounted when the component renders. ```typescript const MyComponent = () => { const { count } = counterLogic.useValues() return
{count}
} // Component is wrapped and logic is auto-mounted export default counterLogic.wrap(MyComponent) ``` -------------------------------- ### useActions() Source: https://github.com/keajs/kea/blob/master/_autodocs/api-reference/react-hooks.md Get all action creators from a logic for dispatching actions. Actions do not trigger re-renders on their own and are stable across renders. ```APIDOC ## useActions() ### Description Get all action creators from a logic for dispatching actions. Actions do not trigger re-renders on their own and are stable across renders. ### Signature ```typescript function useActions( logic: BuiltLogic | LogicWrapper, ): L['actions'] ``` ### Parameters #### Path Parameters * None #### Query Parameters * None #### Request Body * None ### Parameters - **logic** (BuiltLogic | LogicWrapper) - Required - The logic to get actions from ### Return Type `L['actions']` - Object with all action creators. ### Request Example ```typescript function Counter() { const { increment, decrement } = counterLogic.useActions() return (
) } ``` ### Response #### Success Response (200) - **actions** (object) - Object with all action creators. #### Response Example ```json { "increment": "function", "decrement": "function" } ``` ### Notes - Actions don't trigger re-renders on their own - Use with values or selectors to display state changes - Action functions are stable across renders ``` -------------------------------- ### Connect Multiple Kea Logics Source: https://github.com/keajs/kea/blob/master/_autodocs/INDEX.md Compose logic by connecting to other Kea logics. This example demonstrates how to access values and actions from 'otherLogic'. ```typescript const logic = kea([ connect({ values: [otherLogic, ['value1', 'value2 as alias']], actions: [otherLogic, ['action1']], }), ]) ``` -------------------------------- ### Kea Listeners Plugin Example Source: https://github.com/keajs/kea/blob/master/docs/CHANGES-1.0.md The kea-listeners plugin allows listening for actions and running code afterwards. It provides a lightweight alternative to sagas for dispatching actions and accessing state. ```javascript kea({ listeners: ({ actions, selectors }) => ({ [actions.updateName]: (action, { dispatch, getState }) => { console.log(action.payload) dispatch(actions.updateDescription('asd')) const description = selectors.description(getState()) console.log(description) }, }) }) ``` -------------------------------- ### Activate Already Installed Plugin Source: https://github.com/keajs/kea/blob/master/_autodocs/errors.md This error is triggered when attempting to activate the same plugin more than once. Ensure that each plugin is activated only a single time. ```typescript const plugin = { name: 'test', events: {} } activatePlugin(plugin) activatePlugin(plugin) // Error! ``` ```typescript // Only activate once activatePlugin(plugin) ``` -------------------------------- ### Basic Counter Logic with React Integration Source: https://github.com/keajs/kea/blob/master/_autodocs/REFERENCE.md This snippet demonstrates how to create a basic counter logic using Kea, including actions, reducers, selectors, and integrating it with a React component. Use this as a starting point for simple state management needs. ```typescript import { kea, actions, reducers, selectors } from 'kea' const counterLogic = kea([ actions({ increment: () => null, decrement: () => null, }), reducers({ count: [0, { increment: (state) => state + 1, decrement: (state) => state - 1, }], }), selectors({ doubleCount: [(s) => [s.count], (count) => count * 2], }), ]) function Counter() { const { count, doubleCount } = counterLogic.useValues() const { increment, decrement } = counterLogic.useActions() return (

Count: {count}

Double: {doubleCount}

) } export default counterLogic.wrap(Counter) ``` -------------------------------- ### Multiple Event Handlers for Kea Logic Source: https://github.com/keajs/kea/blob/master/_autodocs/api-reference/defaults-events.md Configure multiple lifecycle event handlers within a single `events()` call. This example demonstrates handling both `afterMount` and `beforeUnmount`. ```typescript const listLogic = kea([ events({ afterMount: () => { console.log('List mounted') loadInitialData() }, beforeUnmount: () => { console.log('Cleaning up...') stopPolling() }, }), ]) ``` -------------------------------- ### Initialize Production Context with Plugins Source: https://github.com/keajs/kea/blob/master/_autodocs/api-reference/context.md Set up the Kea context for production by including necessary plugins and disabling debug logging. Ensure plugins are imported and passed in the plugins array. ```typescript import { resetContext } from 'kea' import { loaderPlugin } from 'kea-loaders' resetContext({ plugins: [loaderPlugin], debug: false, }) ``` -------------------------------- ### Get Logic Values with useValues() Source: https://github.com/keajs/kea/blob/master/_autodocs/api-reference/react-hooks.md Use `useValues()` to get all values from a Kea logic. Each property access triggers a selector and may cause re-renders. Unused selectors are not subscribed to. ```typescript function Counter() { const { count, doubleCount } = counterLogic.useValues() return
Count: {count}, Double: {doubleCount}
} ``` -------------------------------- ### keaReducer() Source: https://github.com/keajs/kea/blob/master/_autodocs/api-reference/store-plugins.md Gets or creates the combined Kea reducer for a context. This function is useful for integrating Kea with React-Redux. ```APIDOC ## keaReducer() ### Description Get or create the combined Kea reducer for a context. ### Signature ```typescript function keaReducer(options?: Record): Reducer ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **options** (Object) - Optional - Reducer options ### Return Type `Reducer` - Redux reducer function. ### Examples #### Use with React-Redux ```typescript import { keaReducer, getContext } from 'kea' import { Provider } from 'react-redux' const store = getContext().store export default function App() { return ( ) } ``` ### Notes - Combines all dynamic reducers registered with Kea - Attached to the root reducer by the core plugin - Handles mounting/unmounting of dynamic reducers ``` -------------------------------- ### Initialize Kea with Context Source: https://github.com/keajs/kea/blob/master/docs/CHANGES-1.0.md Previously, Kea was initialized with `getStore()`. In Kea 1.0, initialize Kea with `resetContext()` and fetch the store from the context. ```javascript resetContext({ createStore: { /* `true` or arguments for the old getStore if any */ } }) ``` ```javascript function App ({ children }) { const { store } = getContext() return ( {children} ) ) ``` -------------------------------- ### useAllValues() Source: https://github.com/keajs/kea/blob/master/_autodocs/api-reference/react-hooks.md Get all values from a logic, subscribing to all selectors at once. This hook causes the component to re-render if any value changes. ```APIDOC ## useAllValues() ### Description Get all values from a logic, subscribing to all selectors at once. This hook causes the component to re-render if any value changes. ### Signature ```typescript function useAllValues( logic: BuiltLogic | LogicWrapper, ): L['values'] ``` ### Parameters #### Path Parameters * None #### Query Parameters * None #### Request Body * None ### Parameters - **logic** (BuiltLogic | LogicWrapper) - Required - The logic to get values from ### Return Type `L['values']` - Object with all logic values. ### Request Example ```typescript function Dashboard() { const values = todoLogic.useAllValues() // All selectors are subscribed, component re-renders on any change return (

{values.todos.length} todos

Filter: {values.filter}

) } ``` ### Response #### Success Response (200) - **values** (object) - Object with all logic values. #### Response Example ```json { "todos": [], "filter": "all" } ``` ### Difference from useValues() - `useValues()`: Values are lazy-loaded, only used values trigger re-renders - `useAllValues()`: All values subscribed immediately, any change causes re-render ### Notes - Use when you need multiple values and component should update with any change - May cause unnecessary re-renders if only some values are used ``` -------------------------------- ### createStore() Source: https://github.com/keajs/kea/blob/master/_autodocs/api-reference/store-plugins.md Creates a Redux store for a given context. It accepts an options object to customize store creation, including middleware, enhancers, and preloaded state. ```APIDOC ## createStore() ### Description Create a Redux store for a context. ### Signature ```typescript function createStore(options: Partial = {}): Store ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **options** (Partial) - Optional - Store creation options ### Return Type `Store` - Redux store instance. ### CreateStoreOptions ```typescript interface CreateStoreOptions { paths: string[] reducers: Record preloadedState: Record | undefined middleware: Middleware[] compose: typeof compose enhancers: StoreEnhancer[] plugins: KeaPlugin[] } ``` ### Examples #### Automatic Creation ```typescript import { resetContext, getContext } from 'kea' resetContext({ createStore: true, // default, creates store automatically }) const store = getContext().store ``` #### Custom Store with Options ```typescript import { resetContext, createStore } from 'kea' resetContext({ createStore: false, // don't auto-create }) const store = createStore({ middleware: [customMiddleware], }) ``` #### With Redux DevTools ```typescript import { resetContext, createStore } from 'kea' import { composeWithDevTools } from 'redux-devtools-extension' resetContext({ createStore: { compose: composeWithDevTools(), }, }) ``` #### Preloaded State ```typescript import { createStore } from 'kea' const store = createStore({ preloadedState: { scenes: { home: { isLoading: false, }, }, }, }) ``` ### Notes - Automatically called when accessing `getContext().store` if `createStore: true` - Called after all plugins are activated - `plugins` option populated by `activatePlugin()` - Returns standard Redux store ``` -------------------------------- ### Callable Syntax Source: https://github.com/keajs/kea/blob/master/_autodocs/api-reference/kea.md Demonstrates the different ways a LogicWrapper can be invoked directly. ```APIDOC ## Callable Syntax LogicWrapper can be called directly with three patterns: ```typescript // Build without props const builtLogic = logic() const builtLogic = logic.build() // Build with props const builtLogic = logic({ id: 5 }) const builtLogic = logic.build({ id: 5 }) // Wrap React component const WrappedComponent = logic(MyComponent) const WrappedComponent = logic.wrap(MyComponent) ``` ``` -------------------------------- ### Manually Setting Store on Kea Context Source: https://github.com/keajs/kea/blob/master/docs/CHANGES-1.0.md If setting up the store manually, attach `keaReducer`s to Kea's context after store creation. ```javascript getContext().store = store ``` -------------------------------- ### Kea Actions with Reducers Source: https://github.com/keajs/kea/blob/master/_autodocs/api-reference/actions.md Demonstrates how to define actions and immediately use them within reducers to manage state changes. ```typescript const counterLogic = kea([ actions({ increment: () => null, decrement: () => null, }), reducers({ count: [0, { increment: (state) => state + 1, decrement: (state) => state - 1, }], }), ]) ``` -------------------------------- ### useValues() Source: https://github.com/keajs/kea/blob/master/_autodocs/api-reference/react-hooks.md Get all values from a logic as an object. Each property access triggers a selector and may cause re-renders. Unused selectors are not subscribed to. ```APIDOC ## useValues() ### Description Get all values from a logic as an object. Each property access triggers a selector and may cause re-renders. Unused selectors are not subscribed to. ### Signature ```typescript function useValues( logic: BuiltLogic | LogicWrapper, ): L['values'] ``` ### Parameters #### Path Parameters * None #### Query Parameters * None #### Request Body * None ### Parameters - **logic** (BuiltLogic | LogicWrapper) - Required - The logic to get values from ### Return Type `L['values']` - Object with all logic values. Each access triggers a selector. ### Request Example ```typescript function Counter() { const { count, doubleCount } = counterLogic.useValues() return
Count: {count}, Double: {doubleCount}
} ``` ### Response #### Success Response (200) - **values** (object) - Object with all logic values. #### Response Example ```json { "count": 0, "doubleCount": 0 } ``` ### Notes - Each property access on the returned object uses a selector and may trigger React re-renders - Property access is lazy - unused selectors aren't subscribed to - Automatically mounts/unmounts the logic in the React lifecycle ``` -------------------------------- ### Connect Logic with Dynamic Keying Source: https://github.com/keajs/kea/blob/master/docs/CHANGES-1.0.md Use the `{ connect: props => ({ }) }` format to connect to logic that requires dynamic keying based on component props. This enables granular data fetching and state management. ```javascript const faqImageLogic = kea({ connect: ({ id }) => ({ values: [ faqLogic({ id }), ['isVisible'] ] }), // other logic for the image... }) function RawFaqImage ({ id, title, isVisible }) { if (!isVisible) { return null } return {title} } const FaqImage = faqImageLogic(RawFaqImage) function AllFaqs () { const faqs = [ /* { id, title, body }, ... */ ] return (
{faqs.map(faq => ( <> ))}
) } ``` -------------------------------- ### Kea Router Plugin Example Source: https://github.com/keajs/kea/blob/master/docs/CHANGES-1.0.md The kea-router plugin bridges Kea with react-redux and connected-react-router. It maps actions to URLs and URLs back to actions. ```javascript kea({ actionToUrl: ({ actions }) => ({ [actions.selectEmail]: () => `/signup?type=email`, [actions.unselectEmail]: () => `/signup`, [actions.openLesson]: ({ id }, action) => `/open/${id}` }), urlToAction: ({ actions }) => ({ '/signup?type=email': url => actions.selectEmail(), '/signup': url => actions.unselectEmail(), '/open/': (url) => actions.openLesson(parseInt(url.split('/')[2])) }), }) ``` -------------------------------- ### Configuring Kea Context with Plugins Source: https://github.com/keajs/kea/blob/master/docs/CHANGES-1.0.md Shows how to reset and configure the Kea context, including adding plugins like sagaPlugin and localStoragePlugin. This is typically done at the top of the application and is crucial for server-side rendering. ```javascript resetContext({ plugins: [sagaPlugin, localStoragePlugin], // other options like defaults, plugin config, redux strategy, debug mode, etc }) ``` -------------------------------- ### afterMount() Source: https://github.com/keajs/kea/blob/master/_autodocs/api-reference/defaults-events.md A shorthand for `events({ afterMount: ... })`. This function allows you to execute code after a logic component has been mounted and is ready. It's useful for initializing data or performing actions that depend on the logic being fully set up. ```APIDOC ## afterMount() ### Description Shorthand for `events({ afterMount: ... })`. Executes code after a logic component has been mounted and is ready. ### Method Signature ```typescript function afterMount( input: (logic: L) => void, ): LogicBuilder ``` ### Usage Example ```typescript const dataLogic = kea([ afterMount((logic) => { console.log('Loading data for', logic.path) fetch('/api/data').then(r => r.json()).then(console.log) }), ]) ``` ``` -------------------------------- ### Define Selectors with Kea Source: https://github.com/keajs/kea/blob/master/_autodocs/INDEX.md Use selectors to derive computed values from state. This example shows how to define a selector that doubles the 'count' value. ```typescript const logic = kea([ reducers({ count: [0, {}] }), selectors({ doubled: [(s) => [s.count], (c) => c * 2], }), ]) ``` -------------------------------- ### Mount Logic with BindLogic or wrap() Source: https://github.com/keajs/kea/blob/master/_autodocs/configuration.md Mount logic using the BindLogic component or the logic.wrap() utility. These methods ensure the logic is properly mounted within the component tree. ```typescript // Option 3: Use BindLogic or logic.wrap() ``` -------------------------------- ### Basic Kea Logic Definition Source: https://github.com/keajs/kea/blob/master/_autodocs/api-reference/kea.md Defines a simple counter logic with actions, reducers, and selectors. This is a fundamental example of how to structure Kea logic. ```typescript import { kea, actions, reducers, selectors } from 'kea' const counterLogic = kea([ actions({ increment: () => null, decrement: () => null, }), reducers({ count: [0, { increment: (state) => state + 1, decrement: (state) => state - 1, }], }), selectors({ doubleCount: [(s) => [s.count], (count) => count * 2], }), ]) ``` -------------------------------- ### useMountedLogic() Source: https://github.com/keajs/kea/blob/master/_autodocs/api-reference/react-hooks.md Mount a logic and get the built logic instance. This hook ensures the logic is mounted within the React component's lifecycle. ```APIDOC ## useMountedLogic() ### Description Mount a logic and get the built logic instance. This hook ensures the logic is mounted within the React component's lifecycle. ### Signature ```typescript function useMountedLogic( logic: BuiltLogic | LogicWrapper, ): BuiltLogic ``` ### Parameters #### Path Parameters * None #### Query Parameters * None #### Request Body * None ### Parameters - **logic** (BuiltLogic | LogicWrapper) - Required - The logic to mount ### Return Type `BuiltLogic` - The mounted logic instance. ### Request Example ```typescript function ItemDetail({ itemId }: { itemId: number }) { const logic = useMountedLogic(itemLogic({ id: itemId })) // Component has full access to the logic instance return
{logic.values.name}
} ``` ### Response #### Success Response (200) - **logicInstance** (BuiltLogic) - The mounted logic instance. #### Response Example ```json { "logicInstance": "object" } ``` ``` -------------------------------- ### useAsyncActions() Source: https://github.com/keajs/kea/blob/master/_autodocs/api-reference/react-hooks.md Get async versions of action creators that return Promises. Useful for waiting for side effects like API calls to complete. ```APIDOC ## useAsyncActions() ### Description Get async versions of action creators that return Promises. Useful for waiting for side effects like API calls to complete. ### Signature ```typescript function useAsyncActions( logic: BuiltLogic | LogicWrapper, ): L['asyncActions'] ``` ### Parameters #### Path Parameters * None #### Query Parameters * None #### Request Body * None ### Parameters - **logic** (BuiltLogic | LogicWrapper) - Required - The logic to get async actions from ### Return Type `L['asyncActions']` - Object with async action creators returning Promises. ### Request Example ```typescript function UserProfile() { const { fetchUser } = userLogic.useAsyncActions() const { user } = userLogic.useValues() const handleLoad = async () => { try { await fetchUser(5) console.log('User loaded') } catch (error) { console.error('Failed to load user') } } return (
{user &&

{user.name}

}
) } ``` ### Response #### Success Response (200) - **asyncActions** (object) - Object with async action creators returning Promises. #### Response Example ```json { "fetchUser": "function" } ``` ### Notes - Async actions return Promises that resolve when all listeners complete - Useful for waiting for side effects to complete (e.g., API calls) - Requires listeners to be defined for the actions to be async ``` -------------------------------- ### Dynamic Logics with Key and Props Source: https://github.com/keajs/kea/blob/master/_autodocs/REFERENCE.md This snippet shows how to create dynamic logic instances based on props, using `key` and `props`. This pattern is useful when you need separate logic states for different items, identified by an ID or other properties. ```typescript const itemLogic = kea([ key((props) => props.id), props({ id: 0 } as { id: number }), reducers({ name: ['', { /* ... */ }], }), ]) // Create separate instances per id const item1 = itemLogic({ id: 1 }) const item2 = itemLogic({ id: 2 }) ``` -------------------------------- ### Reducer Definition Formats Source: https://github.com/keajs/kea/blob/master/_autodocs/api-reference/reducers.md Illustrates different formats for defining reducers, including initial value, options, and action handlers. ```typescript // Format 1: [initialValue, actionHandlers] count: [0, { increment: (state) => state + 1, decrement: (state) => state - 1, }] ``` ```typescript // Format 2: [initialValue, options, actionHandlers] count: [0, { some: 'option' }, { increment: (state) => state + 1, }] ``` ```typescript // Format 3: Just action handlers (initial value = null) status: { setStatus: (_, { status }) => status, } ``` ```typescript // Format 4: Function returning initial value count: [ (state, props) => props.initialCount ?? 0, { increment: (state) => state + 1, } ] ``` -------------------------------- ### Single Event Handler for Kea Logic Source: https://github.com/keajs/kea/blob/master/_autodocs/api-reference/defaults-events.md Define a single lifecycle event handler using `events()`. This example shows how to log a message when the logic mounts. ```typescript const dataLogic = kea([ events({ afterMount: () => { console.log('Data logic mounted') }, }), ]) ``` -------------------------------- ### Mount Keyed Kea Logic Without React Source: https://github.com/keajs/kea/blob/master/docs/CHANGES-1.0.md For keyed logic, first build the logic instance with specific keys, then mount it. This is necessary when logic depends on dynamic identifiers. ```javascript const { store } = getContext() const logic = kea({ key: ({ id }) => id, /* some actions and reducers */}) const builtLogic = logic({ id: 12 }) const unmount = builtLogic.mount() store.dispatch(builtLogic.actions.someAction('value')) const state = builtLogic.selectors.getValue(store.getState()) unmount() ``` -------------------------------- ### Kea Context Options Source: https://github.com/keajs/kea/blob/master/_autodocs/configuration.md Configure Kea context options during application startup using resetContext or openContext. ```typescript resetContext({ plugins: [plugin1, plugin2], createStore: true, defaults: {}, debug: false, proxyFields: true, flatDefaults: false, attachStrategy: 'dispatch', detachStrategy: 'dispatch', defaultPath: ['kea', 'logic'], disableAsyncActions: false, }) ``` -------------------------------- ### Kea Immer Plugin Example Source: https://github.com/keajs/kea/blob/master/docs/CHANGES-1.0.md The kea-immer plugin enables mutable state updates in reducers by specifying `{ immer: true }`. This allows direct modification of state objects. ```javascript @kea({ actions: () => ({ increment: (amount = 1) => ({ amount }), decrement: (amount = 1) => ({ amount }) }), reducers: ({ actions, key, props }) => ({ counter: [{ count: 0 }, PropTypes.object, { immer: true }, { [actions.increment]: (state, payload) => { state.count += payload.amount }, [actions.decrement]: (state, payload) => { state.count -= payload.amount } }] }) }) ``` -------------------------------- ### Mount Logic Before Use Source: https://github.com/keajs/kea/blob/master/_autodocs/errors.md To prevent production app crashes with 'not mounted', ensure all logics are mounted before they are accessed. This can be done manually, via hooks, or `BindLogic`. ```typescript // Always mount before accessing const built = logic.build() built.mount() // Or use hooks in React function Component() { const { values } = logic.useValues() } // Or use BindLogic ``` -------------------------------- ### Dispatch Actions with useActions() Source: https://github.com/keajs/kea/blob/master/_autodocs/api-reference/react-hooks.md Use `useActions()` to get all action creators from a Kea logic for dispatching actions. Action functions are stable across renders and do not trigger re-renders on their own. ```typescript function Counter() { const { increment, decrement } = counterLogic.useActions() return (
) } ``` -------------------------------- ### Create Dynamic Kea Logics with Key and Props Source: https://github.com/keajs/kea/blob/master/_autodocs/INDEX.md Define dynamic logic instances using 'key' and 'props'. This allows for multiple instances of the same logic, each identified by unique properties. ```typescript const logic = kea([ key((props) => props.id), props({ id: 0 } as { id: number }), // ... ]) const instance = logic({ id: 5 }) ``` -------------------------------- ### Constants Access in Kea Logic Source: https://github.com/keajs/kea/blob/master/docs/CHANGES-1.0.md Direct access to constants on unbuilt keyed logic as a property is no longer supported. Constants can still be used within the logic, for example, in reducers. ```javascript const logic = kea({ constants: () => ['SOMETHING', 'BLABLA'] }) logic.constants == { SOMETHING: 'SOMETHING', BLABLA: 'BLABLA' } ``` ```javascript const logic = kea({ key: props => props.id, constants: () => ['SOMETHING', 'BLABLA'] }) logic.constants == undefined ``` ```javascript const logic = kea({ key: props => props.id, constants: () => ['SOMETHING', 'BLABLA'], reducers: ({ constants }) => ({ bla: [contants.SOMETHING, { ... }] }) }) ``` -------------------------------- ### Mounting Kea Logic Outside React Source: https://github.com/keajs/kea/blob/master/_autodocs/api-reference/kea.md Demonstrates mounting a logic instance directly using `build()` and `mount()`, bypassing React. It shows how to access values and unmount the logic. ```typescript const builtLogic = logic.build() const unmount = builtLogic.mount() // Use the logic... console.log(builtLogic.values.count) // Clean up unmount() ``` -------------------------------- ### ContextOptions Source: https://github.com/keajs/kea/blob/master/_autodocs/api-reference/context.md Defines the configuration options available when creating or resetting the Kea context. These options control various aspects of Kea's behavior, including plugin activation, store creation, and default reducer values. ```APIDOC ## ContextOptions ### Description Options for context creation. These options are set at context creation time and affect how logics are built and reducers are attached. Plugin-specific options are handled by the respective plugins. ### Interface Definition ```typescript interface ContextOptions extends Partial { plugins?: KeaPlugin[] createStore?: boolean | Partial defaults?: Record } interface InternalContextOptions { debug: boolean proxyFields: boolean flatDefaults: boolean attachStrategy: 'dispatch' | 'replace' detachStrategy: 'dispatch' | 'replace' | 'persist' defaultPath: string[] disableAsyncActions: boolean } ``` ### Parameters #### Path Parameters - **plugins** (KeaPlugin[]) - Optional - Plugins to activate. Defaults to `[]`. - **createStore** (boolean | object) - Optional - Whether to create Redux store, or store options. Defaults to `true`. - **defaults** (Object) - Optional - Default reducer values. Defaults to `{}`. - **debug** (boolean) - Optional - Enable debug logging. Defaults to `false`. - **proxyFields** (boolean) - Optional - Allow accessing logic fields directly. Defaults to `true`. - **flatDefaults** (boolean) - Optional - Use flat default structure. Defaults to `false`. - **attachStrategy** (string) - Optional - How to attach dynamic reducers. Defaults to `'dispatch'`. - **detachStrategy** (string) - Optional - How to detach dynamic reducers. Defaults to `'dispatch'`. - **defaultPath** (string[]) - Optional - Default path for logics. Defaults to `['kea', 'logic']`. - **disableAsyncActions** (boolean) - Optional - Disable async action tracking. Defaults to `false`. ### Examples #### Development Context ```typescript import { resetContext } from 'kea' resetContext({ debug: true, defaults: { scenes: { home: { isLoading: false, }, }, }, }) ``` #### Production Context with Plugins ```typescript import { resetContext } from 'kea' import { loaderPlugin } from 'kea-loaders' resetContext({ plugins: [loaderPlugin], debug: false, }) ``` #### Custom Store Creation ```typescript import { resetContext } from 'kea' import { composeWithDevTools } from 'redux-devtools-extension' resetContext({ createStore: { compose: composeWithDevTools(), }, }) ``` ### Notes - Options set at context creation time. - Most options affect how logics are built and reducers attached. - Plugin-specific options handled by plugins. - Call `resetContext()` during app initialization. ``` -------------------------------- ### Listener with Previous State Access Source: https://github.com/keajs/kea/blob/master/_autodocs/api-reference/listeners.md An example of a listener for the `submit` action that accesses the `previousState` and `currentState` to detect changes. This is useful for auditing or conditional logic based on state transitions. ```typescript const formLogic = kea([ actions({ submit: () => null, }), listeners({ submit: ({ payload }, breakpoint, action, previousState) => { const changes = detectChanges(previousState, currentState) if (changes.length > 0) { console.log('Form changed:', changes) } }, }), ]) ``` -------------------------------- ### Kea Core Import Source: https://github.com/keajs/kea/blob/master/_autodocs/INDEX.md Import the main 'kea' function to define your logic. ```typescript // Main import { kea } from 'kea' ```