Skip to main content

What does split() do?

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

ScenarioWhat split does
Handling different action typesSplits "login", "signup", "logout"
Splitting an effect's outcomessuccess / failure
Filtering by data statusactive / archived / deleted
Branching business logicdepending 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.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.