<Dynamic component={...}>: Element Switching Without Full Re-Creation
- Last updated
- Prerequisites:
- SolidJS Components Run Once
- SolidJS JSX
- solidjs
- Dynamic
- components
- polymorphism
- rendering
- control-flow
Read at your depth
The practical view
`<Dynamic component={componentAccessor()}>` renders a component or HTML tag dynamically based on a reactive signal or prop. `import { Dynamic } from 'solid-js/web';`. You can pass either component functions (`<Dynamic component={MyComponent} />`) or HTML tag string names (`<Dynamic component="h1" />`). When the `component` signal updates, Solid swaps only the dynamic element.
The same idea in other frameworks
`const Tag = tagSignal; return <Tag {...props} />;` inside render.`<ng-container *ngComponentOutlet="componentType"></ng-container>`.`<component :is="currentComponent" />`.`<svelte:component this={currentComponent} />`.Legacy vs modern
Nested Ternary Component Switching vs <Dynamic>
Ternary trees for dynamic tags become unreadable; `<Dynamic>` cleanly maps runtime tags and components.
{tag() === 'h1' ? <h1>{text}</h1> : tag() === 'h2' ? <h2>{text}</h2> : <p>{text}</p>} // ❌ Repetitive<Dynamic component={level()} class="title">{children}</Dynamic> // ✅ NEW: Clean & polymorphicInterview gotchas
Context
Tests knowledge of polymorphic component capabilities.
The mechanical answer
Yes. If `component` is passed a string (e.g. `'div'`, `'button'`, `'svg'`), `<Dynamic>` creates a native DOM element with the provided props. If `component` is passed a component function reference (e.g. `MyCustomButton`), it invokes `createComponent(component, props)`.
Trap
Passing an invalid value like `null` or `undefined` to `component` will result in `<Dynamic>` rendering nothing (an empty text node).
Context
Checks understanding of prop forwarding in Solid control flow.
The mechanical answer
Props passed to `<Dynamic component={tag()} {...otherProps} />` are wrapped in a reactive proxy. When `tag()` changes, the previous component instance and its reactive scope are disposed, and the new component is instantiated with the same reactive `otherProps` proxy without requiring re-binding.
Trap
Do not destructure props before passing them into `<Dynamic>`, as destructuring breaks prop reactivity.