createEffect
Creates a reactive effect with separate compute and effect phases.
compute(prev)runs reactively — put all reactive reads here. The returned value is passed toeffectand is also the new "previous" value for the next run.effect(next, prev?)runs imperatively (untracked) after the queue flushes. Put DOM writes / fetch / logging / subscriptions here. It may return a cleanup function which runs before the next effect or on disposal.
Reactive reads inside effect will not re-trigger this effect — that's
intentional. If you need a single-phase tracked effect, use
createTrackedEffect (with the tradeoffs noted there).
Pass an EffectBundle ({ effect, error }) instead of a plain function to
intercept errors thrown from the compute or effect phases.
createEffect<T>(compute, effectFn | { effect, error }, options?: EffectOptions);Deprecated:
createEffect(compute)(single argument) is no longer supported. Pass a separate effect function as the second argument:createEffect(compute, effect). SeeMISSING_EFFECT_FN.
- For a side effect that reacts to changes, split the work:
createEffect(() => signal(), value => doWork(value)). - For a derived value, use
createMemo(() => signal()). - For a one-shot side effect at construction time, just call the function.
Import
import { createEffect } from "solid-js";Type signature
function createEffect<T>( compute: ComputeFunction<undefined | NoInfer<T>, T>, effectFn: EffectFunction<NoInfer<T>, T> | EffectBundle<NoInfer<T>, T>, options?: EffectOptions): void;function createEffect<T>( compute: ComputeFunction<undefined | NoInfer<T>, T>): never;Parameters
compute
A function that receives its previous value and returns a new value used to react on a computation
effectFn
A function that receives the new value and is used to perform side effects (return a cleanup function), or an EffectBundle with effect and error handlers
options
EffectOptions -- name, defer, schedule
Examples
const [count, setCount] = createSignal(0);
createEffect( () => count(), // compute: tracks `count` (value) => console.log(value) // effect: side effect);
setCount(1); // logs 1 after the next flushcreateEffect( () => userId(), (id) => { const ctrl = new AbortController(); fetch(`/users/${id}`, { signal: ctrl.signal }); return () => ctrl.abort(); // cleanup before next run / disposal });Related types
ComputeFunction
type ComputeFunction<Prev, Next extends Prev = Prev> = ( v: Prev) => PromiseLike<Next> | AsyncIterable<Next> | Next;EffectBundle
type EffectBundle<Prev, Next extends Prev = Prev> = { effect: EffectFunction<Prev, Next>; error: (err: unknown, cleanup: () => void) => void;};effect
- Type:
EffectFunction<Prev, Next>
error
- Type:
(err: unknown, cleanup: () => void) => void
EffectFunction
type EffectFunction<Prev, Next extends Prev = Prev> = ( v: Next, p?: Prev) => (() => void) | void;EffectOptions
Options for effect primitives that support deferring/scheduling their initial run (createEffect, createRenderEffect, createReaction).
interface EffectOptions extends BaseEffectOptions { defer?: boolean; schedule?: boolean; sync?: boolean;}defer
- Type:
boolean
When true, defers the initial effect execution until the next change
schedule
- Type:
boolean
When true, enqueues the initial effect callback through the effect queue instead of running
it synchronously at creation. Lets the initial run participate in transitions -- if any
source throws NotReadyError during the compute phase, the callback is held until the
transition settles.
Primarily for render effects that need transition-aware initial mounts (e.g. The root
insert() in render()).
sync
- Type:
boolean
Advanced. When true, asserts the compute function returns synchronous
values only (never PromiseLike / AsyncIterable). Skips the
async-shape probe in recompute for a small fixed-cost win per run.
Intended for compiler emissions (_$effect) and library code that
provably returns sync values. Returning a Promise or async iterable
from a sync: true effect is undefined behavior — the value will be
stored as-is and never awaited.