Control Flow

The If, For, and Switch functions render conditionals and lists. They can read Cells and update the rendered output when their values change.

Conditional Rendering with If

If shows or hides interface content based on a condition.

It takes a Cell (or any regular value) and branches based on whether the value is true or false.

import { If, Cell } from 'retend';

function ToggleMessage() {
  const show = Cell.source(false);
  const toggle = () => show.set(!show.get());

  return (
    <div>
      <button type="button" onClick={toggle}>
        Toggle Message
      </button>

      {If(show, {
        true: () => <p>The message is visible!</p>,
        false: () => <p>The message is hidden.</p>,
      })}
    </div>
  );
}

When only the true branch is provided:

{
  If(show, {
    true: () => <p>Only shows when the Cell is true.</p>,
  });
}

Standard JavaScript ternary statements (isOn ? true : false) and && operators do not connect to Retend's reactivity system when the data changes. If is used for conditional interface content that can change.

Shorthand Syntax

For a truthy branch without a false branch, a function is passed instead of an object:

{
  If(show, (value) => <p>The value is: {value}</p>);
}

An object with true and false branches can be passed instead of separate callbacks.

{
  If(show, {
    true: () => <p>Visible!</p>,
    false: () => <p>Hidden.</p>,
  });
}

Rendering Lists with For

For renders an array as a list of elements.

It takes the array and a callback that returns the JSX for each item.

import { For, Cell } from 'retend';

function ItemList() {
  const items = Cell.source([
    { id: 1, name: 'Apple' },
    { id: 2, name: 'Banana' },
  ]);

  return (
    <ul>
      {For(
        items,
        (item, index) => (
          <li>
            Item {index}: {item.name}
          </li>
        ),
        { key: 'id' }
      )}
    </ul>
  );
}

The index parameter is a reactive Cell<number>, not a plain number. It can be passed directly into JSX. index.get() is called before using it in a calculation.

Keys in Lists

When rendering a list of objects that can change, a key is provided in the final options object.

The key identifies each item so Retend can update the list. It is set to the name of a unique ID property, such as key: 'id'.

Multi-State Rendering with Switch

Switch handles a value with more than two states, such as loading, success, and error.

import { Switch, Cell } from 'retend';

function DataFetcher() {
  const status = Cell.source('loading');

  return (
    <div>
      {Switch(status, {
        loading: () => <p>Fetching data...</p>,
        success: () => <p>Success!</p>,
        error: () => <p>Something went wrong.</p>,
      })}
    </div>
  );
}

Switch looks at the value inside the Cell and runs the matching branch. If the status is "success", it only renders the success branch.

Default Case

A third argument serves as a fallback when the value does not match a defined branch:

{
  Switch(
    status,
    {
      loading: () => <p>Loading...</p>,
      success: () => <p>Done!</p>,
    },
    (value) => <p>Unknown status: {value}</p>
  );
}

If, For, and Switch keep the rendered output synchronized with their input values.