Signal Options Customizing Signal behavior for equality checks and value cloning settings Guide
Categories

Signal Options

To provide more granular control over reactivity, Semantic provides several options which let you control how values are updated and compared.

The default options are designed to permit some minor performance overhead as a tradeoff for improved developer experience, but this might not fit all use-cases for Signals.

Signal options are passed in the second argument to the Signal constructor.

Equality Comparison

By default, Signals use a deep equality comparison, isEqual, to determine if a new value is actually different from the current value. This prevents Reactions from rerunning if the updated value has not changed.

import { Signal } from '@semantic-ui/reactivity';
const person = new Signal({ name: 'John', age: 30 });
// No reactive update triggered (objects are deep equal)
person.set({ name: 'John', age: 30 });
// Reactive update triggered (objects differ)
person.set({ name: 'Jane', age: 30 });

Custom Equality Function

You can provide a custom equality comparison function using the equalityFunction option to modify how equality checks are performed. This can potentially speed up comparisons at the cost of potential additional reactivity.

When To Use Custom equality functions can be useful for extremely large objects or data structures where you want to avoid checking their values each time they are accessed.

const customEquality = (a, b) => {
// Custom comparison logic (e.g., shallow compare, reference compare)
return a === b; // Example: strict reference equality
};
// Signal using custom equality check
const customVar = new Signal(initialValue, { equalityFunction: customEquality });

Safety Presets

Signals have three safety presets controlling how the stored value is protected against accidental mutation. Set the preset via the safety option.

PresetOn setOn .get().x = yDedupeUse case
freeze (default)deep-freeze plain objects and arraysthrows TypeErrorisEqualstate your code owns end-to-end
referencestore rawsilent (no reactivity)isEqualthird-party objects, perf-critical paths
nonestore rawsilent (no reactivity)neverevent-stream semantics — every set notifies

safety: 'freeze' — the default

The default deep-freezes object and array values when you call set(). Accidental in-place mutation throws at the call site instead of silently dropping the update.

const count = new Signal({ n: 0 });
count.get().n = 1; // TypeError — "Signal value is frozen — cannot set property `n`"
// Correct ways to update:
count.set({ n: 1 }); // replace the whole value
count.mutate(prev => ({ n: prev.n + 1 })); // return a new value
count.setProperty('n', 1); // mutation helper — rebuilds immutably under freeze

Deep-freeze only walks arrays and plain objects. Date, Map, Set, RegExp, DOM nodes, and class instances are stored by reference — their own mutation semantics are preserved.

safety: 'reference' — opt-out for borrowed data

Use reference when the signal holds objects you didn’t construct yourself. Freezing them would poison the lender’s internal references; see Signals and Foreign References for the full heuristic.

const searchResults = new Signal([], { safety: 'reference' });

Direct mutation on .get() values fails silently under reference — the helpers (push, splice, setProperty) remain the safe update path.

safety: 'none' — event-stream semantics

Use none when every set should notify subscribers, even if the value is deeply equal to the previous one. Suitable for notification channels where the payload’s shape repeats.

const pulse = new Signal(null, { safety: 'none' });
pulse.set({ type: 'heartbeat' });
pulse.set({ type: 'heartbeat' }); // still notifies, even though isEqual would say equal

Custom Clone Function

The default cloneFunction is used by signal.clone() to produce a deep-mutable copy on demand. Override it if you need non-default clone semantics.

const jsonClone = (value) => JSON.parse(JSON.stringify(value));
const mySignal = new Signal({ data: 1 }, { cloneFunction: jsonClone });
Previous
Debugging
Next
Query