Suggest an editImprove this articleRefine the answer for “What does split() do?”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)`split()` is an operator that **splits a single stream (event/effect)** into **several branches** based on a condition (`match`) or a feature (`cases`). **Key point:** `split` takes one event (`source`) and creates (or routes into) new events, sending the payload to the right branch depending on which condition matched.Shown above the full answer for quick recall.Answer (EN)Image## What `split` is > `split()` is an operator that **splits a single stream (event/effect)** > into **several branches** based on a condition (`match`) or a feature (`cases`). In simpler terms: > "When an event arrives, **send it to the right category** based on its content." --- ## 1. A simple example ```javascript import { createEvent, split } from 'effector' const userAction = createEvent<'login' | 'logout' | 'signup'>() const { login, logout, signup } = split({ source: userAction, match: { login: (type) => type === 'login', logout: (type) => type === 'logout', signup: (type) => type === 'signup', }, }) login.watch(() => console.log('Logged in')) logout.watch(() => console.log('Logged out')) signup.watch(() => console.log('Signed up')) userAction('signup') // → "Signed up" userAction('logout') // → "Logged out" ``` Here `split()` takes **one event** (`userAction`) and creates **three new events** (`login`, `logout`, `signup`), each of which fires only when its own condition matches. --- ## 2. Syntax ```javascript split({ source, // event or effect.doneData match, // an object of filter functions cases?, // an object of ready-made events to assign to }) ``` --- ## 3. Example with a data object ```javascript const formSubmitted = createEvent<{ type: 'login' | 'signup'; data: any }>() const { login, signup } = split({ source: formSubmitted, match: { login: ({ type }) => type === 'login', signup: ({ type }) => type === 'signup', }, }) login.watch(({ data }) => console.log('Logging in:', data)) signup.watch(({ data }) => console.log('Signing up:', data)) formSubmitted({ type: 'signup', data: { name: 'Alex' } }) // → "Signing up: { name: 'Alex' }" ``` `split` simply "routes" the incoming payload to the right event based on the condition. --- ## 4. Example with an effect `split` works great with effects, especially with `.done`, `.fail`, and `.finally`: ```javascript import { createEffect } from 'effector' const fetchUserFx = createEffect(async (id: number) => { const res = await fetch(`/api/users/${id}`) if (!res.ok) throw new Error('Not found') return res.json() }) const { success, failure } = split({ source: fetchUserFx.finally, match: { success: ({ status }) => status === 'done', failure: ({ status }) => status === 'fail', }, }) success.watch(({ result }) => console.log('User:', result)) failure.watch(({ error }) => console.error('Error:', error)) ``` This is a very common pattern: **splitting an effect's successful and unsuccessful outcome** without manual checks. --- ## 5. Using it with pre-created events (`cases`) If events are already declared, you can simply "route" the streams: ```javascript const loginEvent = createEvent() const signupEvent = createEvent() split({ source: userAction, match: { login: (t) => t === 'login', signup: (t) => t === 'signup', }, cases: { login: loginEvent, signup: signupEvent, }, }) ``` Now `userAction('login')` will call `loginEvent()`. --- ## 6. What `split` does under the hood `split()` is like **several** `guard()` calls **in a row**, but with a convenient declarative syntax and automatic event generation. Equivalent to this: ```javascript const login = guard({ source: userAction, filter: (t) => t === 'login' }) const logout = guard({ source: userAction, filter: (t) => t === 'logout' }) ``` But `split()` does all of it for you in one call. --- ## 7. You can add a "default" route If no condition matches, `__` (underscore) fires: ```javascript const action = createEvent<string>() const { ok, fail, __: unknown } = split({ source: action, match: { ok: (v) => v === 'ok', fail: (v) => v === 'fail', }, }) unknown.watch(() => console.warn('Unknown action')) action('cancel') // → "Unknown action" ``` --- ## 8. Typing split in TypeScript Effector smartly infers types for all branches: ```javascript const action = createEvent<'a' | 'b' | 'c'>() const { a, b, c } = split({ source: action, match: { a: (x): x is 'a' => x === 'a', b: (x): x is 'b' => x === 'b', c: (x): x is 'c', }, }) ``` Now `a`, `b`, `c` have **strictly typed payloads** - TypeScript knows that `a` can only be `'a'`. --- ## 9. Visually ```javascript [source event] │ ┌───────────┼────────────┐ ▼ ▼ ▼ [caseA] [caseB] [caseC] ``` Each condition creates its own "stream branch". --- ## 10. Practical scenarios | Scenario | What split does | |---|---| | Handling different action types | Splits "login", "signup", "logout" | | Splitting an effect's outcomes | success / failure | | Filtering by data status | active / archived / deleted | | Branching business logic | depending on the type of user | --- ## Summary > `split()` is a reactive "switch-case" in Effector. > It: > > - takes one stream (`source`), > - checks every `match`, > - creates (or routes into) new events, > - sends the payload to the right branch. --- ### Formula to remember > `split({ source, match: { A, B, C } })` > ⇒ creates `A()`, `B()`, `C()` > ⇒ calls the matching one when its condition is met.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.