Skip to content

batch()

The batch() function defers notifications so dependents run once after all updates complete.

const result = batch(fn)

fn : A function that performs multiple signal writes.

Whatever fn returns.

Normally, each signal write immediately notifies dependents. When updating multiple signals, this can cause redundant recalculations:

const a = signal(1);
const b = signal(2);
const sum = computed(() => a() + b());
effect(() => console.log('Sum:', sum()));
// logs: "Sum: 3"
a(10); // logs: "Sum: 12"
b(20); // logs: "Sum: 30"
// Effect ran twice!

With batch(), updates are deferred until the batch completes:

batch(() => {
a(10);
b(20);
});
// logs: "Sum: 30" (once)

Batches can nest. Updates only flush when the outermost batch completes:

batch(() => {
a(10);
batch(() => {
b(20);
c(30);
});
d(40);
});
// All effects run once, after all updates
const name = signal('');
const email = signal('');
const phone = signal('');
const reset = () => {
batch(() => {
name('');
email('');
phone('');
});
};
const items = signal<Item[]>([]);
const selectedId = signal<string | null>(null);
const filter = signal('all');
const loadData = async () => {
const data = await fetchItems();
batch(() => {
items(data.items);
selectedId(data.defaultSelected);
filter('all');
});
};
const status = signal<'idle' | 'loading' | 'error' | 'success'>('idle');
const data = signal<Data | null>(null);
const error = signal<Error | null>(null);
const setSuccess = (result: Data) => {
batch(() => {
status('success');
data(result);
error(null);
});
};
const setError = (err: Error) => {
batch(() => {
status('error');
data(null);
error(err);
});
};
  • signal() — Create reactive state
  • effect() — Flush strategies like mt() also batch updates