Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Several options: Switch and Match

When there are more than two options, nested Show components get awkward. To choose one branch out of several, Solid has the Switch and Match pair — the counterpart of a switch statement or an if ... else if chain.

Switch and Match

Switch checks the nested Match components from top to bottom and renders the first one whose when condition is truthy:

// src/components/TodoFilter.jsx
import { createSignal, Switch, Match } from 'solid-js';
 
export default function TodoFilter() {
  const [filter, setFilter] = createSignal('all');
 
  return (
    <div>
      <button onClick={() => setFilter('all')}>All</button>
      <button onClick={() => setFilter('active')}>Active</button>
      <button onClick={() => setFilter('done')}>Done</button>
 
      <Switch>
        <Match when={filter() === 'all'}>
          <p>Showing all tasks</p>
        </Match>
        <Match when={filter() === 'active'}>
          <p>Showing active tasks</p>
        </Match>
        <Match when={filter() === 'done'}>
          <p>Showing finished tasks</p>
        </Match>
      </Switch>
    </div>
  );
}

Render <TodoFilter /> in src/App.jsx. A click on a button changes the text under the buttons, and only one paragraph is ever visible.

fallback

If no condition matches, Switch renders the content of its fallback attribute:

// src/components/TodoStatus.jsx
import { Switch, Match } from 'solid-js';
 
export default function TodoStatus(props) {
  return (
    <Switch fallback={<span>Unknown</span>}>
      <Match when={props.status === 'new'}>
        <span>New</span>
      </Match>
      <Match when={props.status === 'progress'}>
        <span>In progress</span>
      </Match>
      <Match when={props.status === 'done'}>
        <span>Done</span>
      </Match>
    </Switch>
  );
}

Usage: <TodoStatus status="progress" /> shows "In progress", and <TodoStatus status="paused" /> shows "Unknown".

Applying the filter to the list

The list itself is easier to filter with a derived function, keeping Switch for different markup:

// src/components/TodoFilter.jsx
const visible = () => {
  if (filter() === 'active') return todos().filter((t) => !t.done);
  if (filter() === 'done') return todos().filter((t) => t.done);
  return todos();
};

Then <For each={visible()}> renders only the matching tasks.

When to use what

SituationComponent
Show or hideShow
Two optionsShow with fallback
Three or more optionsSwitch and Match

Common mistake

Putting something other than Match inside Switch:

// src/components/TodoStatus.jsx
import { Switch, Match } from 'solid-js';
 
export default function TodoStatus(props) {
  return (
    <Switch>
      {/* Wrong: a plain tag inside Switch */}
      {/* <p>Status:</p> */}
      <Match when={props.status === 'done'}>
        <span>Done</span>
      </Match>
    </Switch>
  );
}

Switch understands only Match. Move shared text like "Status:" outside Switch.

Thanks for reading!

Donate to the site — we work hard for you.