Targeted Updates in SolidJS: Signals and createResource for Reactive UIs
Use SolidJS signals for targeted UI state and createResource for declarative async data with cancellation. A concrete search example shows how fine-grained reactivity avoids full re-renders.
19 Oct 2025, 07:44 UTC

The problem is a form or list where changing one field causes the whole component to re-render. In SolidJS, fine-grained reactivity with signals avoids that by updating only the DOM nodes that actually read a changed value.
The thesis is simple: model UI state with signals for synchronous primitives, and model async data with createResource for declarative loading and cancellation. Together they give targeted updates without manual diffing.
Fine-grained reactivity vs coarse re-renders
SolidJS tracks reads synchronously during render or inside reactive primitives like createEffect and createMemo. A signal is a getter/setter pair created by createSignal. When the getter is read in a reactive context, Solid records a dependency. When the setter runs, only dependents re-run.
This differs from coarse virtual DOM diffing where a state change often triggers a full component render and diff. With signals, a primitive change touches only the nodes that depend on it. For nested objects, createStore provides a shallow proxy that preserves fine-grained updates while encouraging immutable-style updates.
Signal reads must occur synchronously in a reactive context for tracking to work. Reads outside render or effects are untracked and will not cause updates.
Async data as a reactive resource
createResource integrates signals with async loading. It takes a source function and a fetcher. The resource exposes data, loading and error states, and refetches automatically when the source signal changes. In-flight fetches are cancelled when the source changes.
Source functions should be pure and inexpensive. Heavy computation or side effects in the source can cause unnecessary refetches and hard-to-trace updates.
Suspense boundaries compose with resources to colocate fallback UI with the component that needs it. The fallback renders while the resource is pending, and the component suspends until data resolves.
Worked example: searchable list with cancellation
The pattern below shows a search input driving a resource. The source signal is the query. The fetcher returns a promise. Changing the query cancels the previous request and starts a new one.
// Assumes SolidJS v1.x
import { createSignal, createResource, Suspense } from 'solid-js';
function fetchItems(query) {
const controller = new AbortController();
const promise = fetch(`/api/items?q=${encodeURIComponent(query)}`, {
signal: controller.signal
}).then(r => r.json());
promise.controller = controller;
return promise;
}
export default function SearchList() {
const [query, setQuery] = createSignal('');
const [source, setSource] = createSignal(query());
const [items] = createResource(source, fetchItems);
function onInput(e) {
setQuery(e.target.value);
// debounce in real code; here we update source directly for clarity
setSource(e.target.value);
}
return (
<div>
<input value={query()} onInput={onInput} placeholder="Search" />
<Suspense fallback=<div>Loading…</div>>
<ul>
{items()?.map(item => <li>{item.name}</li>)}
</ul>
</Suspense>
</div>
);
}
The resource re-runs when source changes. You can verify behavior by changing the source signal and observing network requests in the browser devtools. The fallback should appear on initial load and disappear after resolution.
With SolidStart, source functions run on both server and client during streaming hydration. Keep fetchers safe to run in both environments and avoid client-only globals in the source.
Trade-off: mental model cost
Fine-grained updates reduce DOM work but increase mental model complexity. Developers must reason about where signals are read and which primitives track them. Debugging untracked reads is common when values are accessed outside render or effects.
API surface for SolidStart, server functions and streaming differs across major releases. Verify behavior against the SolidJS major version in use.
Actionable check
Build a minimal component with createSignal and createEffect that logs when the effect runs. Update the signal and confirm only dependent nodes change. Then wrap a createResource in Suspense and change its source to confirm refetch and cancellation. Compare update behavior against a coarse re-render baseline to see the difference in DOM work.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.