Skip to content
On this page

Cells

The Cell is the most basic kind of reactive value. It's a place to store a single value that is updated atomically. Updates to cells take effect immediately.

Deep DiveAtomic, Immediate Updates
Immediate Updates

The value of cell.current is always the value that was last set, immediately after it was set. There is no time delay between when the value is set and when your code sees the update under any circumstances.

Atomic Updates

When we say that a Cell is updated atomically, we mean that updates to the value happen in a single operation, even if the value is a list or object.

This differs from the reactive collections, which allow you to update a part of the collection at once.

Creating a Cell

You create a cell with the Cell function, passing in the cell's initial value.

tsx
import { Cell } from "@starbeam/universal";
 
const cell = Cell(0);
expect(cell.current).toBe(0);
tsx
import { Cell } from "@starbeam/universal";
 
const cell = Cell(0);
expect(cell.current).toBe(0);

Once you've created a cell, you can immediately access its value using the cell's current property.

You Probably Don't Want Cell(null)

In Starbeam, you rarely initialize a cell to null. In Starbeam, there's no time delay between initializing the cell and setting its value, so there's no need to use null to represent that time.

If you use TypeScript, that means that you typically won't need to worry about null checks in situations where null is logically impossible.

Updating a Cell

The simplest way to update a cell is by modifying its current property.

tsx
cell.current = 1;
expect(cell.current).toBe(1);
tsx
cell.current = 1;
expect(cell.current).toBe(1);

Once you've updated a cell, you can immediately access its value using the cell's current property.

The set method

Calling a cell's set method is equivalent to updating its current property.

In-Place Updates

You can use ++, += and other in-place operators to update the cell's value.

tsx
cell.current++;
expect(cell.current).toBe(2);
 
cell.current += 1;
expect(cell.current).toBe(3);
 
cell.current *= 2;
expect(cell.current).toBe(6);
tsx
cell.current++;
expect(cell.current).toBe(2);
 
cell.current += 1;
expect(cell.current).toBe(3);
 
cell.current *= 2;
expect(cell.current).toBe(6);

No Limitations

You can even use the ??= operator to initialize the cell's value if it started with undefined.

tsx
const cell = Cell(undefined as undefined | number);
expect(cell.current).toBe(undefined);
 
cell.current ??= 1;
expect(cell.current).toBe(1);
 
cell.current ??= 2;
expect(cell.current).toBe(1);
tsx
const cell = Cell(undefined as undefined | number);
expect(cell.current).toBe(undefined);
 
cell.current ??= 1;
expect(cell.current).toBe(1);
 
cell.current ??= 2;
expect(cell.current).toBe(1);
tsx
const cell = Cell(undefined);
expect(cell.current).toBe(undefined);
 
cell.current ??= 1;
expect(cell.current).toBe(1);
 
cell.current ??= 2;
expect(cell.current).toBe(1);
tsx
const cell = Cell(undefined);
expect(cell.current).toBe(undefined);
 
cell.current ??= 1;
expect(cell.current).toBe(1);
 
cell.current ??= 2;
expect(cell.current).toBe(1);

Updating Based on the Previous Value

As a convenience, you can use the update function to update a cell based on the previous value.

tsx
cell.update((prev) => prev + 1);
expect(cell.current).toBe(3);
tsx
cell.update((prev) => prev + 1);
expect(cell.current).toBe(3);

You don't ever need to use it, because this will work just as well:

tsx
cell.set(cell.current + 1);
expect(cell.current).toBe(3);
tsx
cell.set(cell.current + 1);
expect(cell.current).toBe(3);

You can even use the ++ shorthand to update cell.current:

tsx
cell.current++;
expect(cell.current).toBe(4);
tsx
cell.current++;
expect(cell.current).toBe(4);

No matter which of these methods you use to update a cell, the value of the cell will always update immediately.

Adding a Debug Description

Whenever you create a reactive value in Starbeam, you can specify a description property. This is a string that is used to describe the value in the developer tools.

tsx
import { Cell } from "@starbeam/universal";
 
const person = Cell({ name: "John", age: 30 }, "person");
tsx
import { Cell } from "@starbeam/universal";
 
const person = Cell({ name: "John", age: 30 }, "person");

If your cell has an equals parameter (see Equivalence), you specify the description of the cell as an additional option.

tsx
const person = Cell(
{ name: "John", age: 30 },
{
equals: (a, b) => a.name === b.name && a.age === b.age,
description: "person",
},
);
tsx
const person = Cell(
{ name: "John", age: 30 },
{
equals: (a, b) => a.name === b.name && a.age === b.age,
description: "person",
},
);

Released under the MIT license