SolidJS in 59 Seconds

Overtime Bonus

SolidJS docs ↗

Lists with <For>

Render one list row for each set.

import { For } from 'solid-js'

const sets = [
  { name: 'Moon Rover' },
  { name: 'Dragon Keep' },
  { name: 'Ocean Treehouse' },
  { name: 'Rainbow Racer' },
]

export function SetList() {
  // For passes each set to the row template.
  return (
    <ul>
      <For each={sets}>
        {(set) => <li>{set.name}</li>}
      </For>
    </ul>
  )
}
  • Moon Rover
  • Dragon Keep
  • Ocean Treehouse
  • Rainbow Racer

Store

createStore groups related values in one reactive object and lets you update individual fields, including nested ones.

import { createStore } from 'solid-js/store'

export function SetEditor() {
  const [card, setCard] = createStore({
    name: 'Moon Rover',
    details: { pieces: 320 },
  })

  // Read store fields directly as properties.
  return (
    <section>
      {/* setCard('name', ...) changes the name. */}
      <input
        aria-label="Set name"
        type="text"
        value={card.name}
        onInput={(event) => setCard('name', event.currentTarget.value)}
      />

      {/* setCard('details', 'pieces', ...) changes the piece count. */}
      <input
        aria-label="Piece count"
        type="range"
        min="100"
        max="800"
        step="10"
        value={card.details.pieces}
        onInput={(event) => setCard('details', 'pieces', Number(event.currentTarget.value))}
      />

      {/* These reads keep the text in sync with both fields. */}
      <p>{card.name} · {card.details.pieces} pieces</p>
    </section>
  )
}
Live cardMoon Rover

320 pieces

Async data

createResource loads asynchronous data and reloads it when its input changes. <Suspense> displays fallback content while it loads.

import { createResource, createSignal, Suspense } from 'solid-js'

const catalog = {
  'Moon Rover': { name: 'Moon Rover', pieces: 320 },
  'Dragon Keep': { name: 'Dragon Keep', pieces: 508 },
}

async function loadProduct(name) {
  await new Promise((resolve) => setTimeout(resolve, 700))
  return catalog[name]
}

export function ProductLoader() {
  const [selectedName, setSelectedName] = createSignal('Moon Rover')

  // Load the selected product again whenever its selectedName changes.
  const [product] = createResource(selectedName, loadProduct)
  const switchProduct = () => {
    setSelectedName((current) =>
      current === 'Moon Rover' ? 'Dragon Keep' : 'Moon Rover'
    )
  }

  return (
    <section>
      <button onClick={switchProduct}>Switch product</button>
      <Suspense fallback={<p>Loading...</p>}>
        {/* product() returns the loaded product; it does not update it.
            ?. handles the time before data arrives. */}
        <p>{product()?.name} · {product()?.pieces} pieces</p>
      </Suspense>
    </section>
  )
}
Loading sample data…

This example uses a local 700 ms delay.