Common Mistakes and Best Practices
A closing checklist of the Solid-specific pitfalls this course covered, and the habits that avoid them.
3 menit membaca
You've now seen every core piece of Solid: signals, memos, effects, components that run once, control-flow components, context, and stores. This closing lesson consolidates the mistakes that come up most often — mostly variations on the same underlying principle repeated throughout this course.
Mistake 1: destructuring props
// Breaks reactivity
function Card({ title, price }) { return <p>{title}: ${price}</p>; }
// Stays reactive
function Card(props) { return <p>{props.title}: ${props.price}</p>; }Covered in depth earlier in the course, and still the single most common bug for developers arriving from React. If you need to reshape props, use splitProps/mergeProps rather than destructuring.
Mistake 2: reading a signal outside a tracked context and expecting updates
function Component() {
const [count, setCount] = createSignal(0);
const snapshot = count(); // read once, frozen forever
return <p>{snapshot}</p>;
}snapshot is a plain number captured during the single execution of Component. The fix is always the same: call count() at the point of use — inside JSX, a memo, or an effect — rather than assigning its result to a variable ahead of time.
Mistake 3: mutating signal state in place
const [list, setList] = createSignal([1, 2, 3]);
// No update triggered — same array reference
list().push(4);
// Correct — new reference
setList([...list(), 4]);Signals compare by reference for objects and arrays. If your state is naturally nested or needs in-place-feeling updates, that's a strong signal (no pun intended) that createStore is the better fit than createSignal.
Mistake 4: passing JSX instead of a function to render
// Wrong — evaluates the JSX immediately, outside a reactive root
render(<App />, document.getElementById("root"));
// Correct — Solid calls this function within a reactive context
render(() => <App />, document.getElementById("root"));This one usually surfaces early (during setup) rather than mid-project, but it's worth keeping in mind any time you see a "render" or "createRoot"-style API in Solid — the function wrapper is what lets reactivity work from the very top of the tree.
Mistake 5: reaching for createMemo or createEffect out of habit
Not every derived value needs createMemo, and not every side-effect-shaped thing needs createEffect. A plain arrow function is enough for cheap derived values; createEffect should be reserved for things that genuinely reach outside the reactive system (DOM APIs, logging, network calls), not as a general-purpose "run this when something changes" hammer.
A short checklist for reviewing your own Solid code
- Are props accessed as
props.xat the point of use, never destructured into a variable? - Are signals always called as
signal(), never assigned to a plain variable before use? - Is state updated by replacing references (signals) or through path setters (stores), never mutated in place?
- Does
<Show>/<For>/<Switch>handle conditional and list rendering, rather than raw ternaries and.mapfor anything beyond the trivial? - Is
createEffectreserved for real side effects, withonCleanupused wherever it starts something ongoing (a timer, subscription, or in-flight request)?
Every one of these traces back to the same idea from the very first lesson: Solid has no virtual DOM and no re-renders, so reactivity has to be threaded through carefully — as function calls, kept alive at the point of use — rather than assumed to refresh automatically the way a React re-render would paper over similar mistakes. Once that habit is automatic, the rest of Solid's API is small enough to hold in your head at once.