Skip to content
On this page

Reactive Builtins

In the previous lesson, we created a second cell to hold our second counter. This works, but there's a nicer way to create multiple pieces of state: reactive builtins.

Reactive builtins are objects that have the same API as builtin JavaScript objects, but they're reactive.

In this lesson, we'll move both counters into a single reactive object.

What We're Building

Open on CodeSandboxOpen Sandbox

The Code

By moving the two counters into a single reactive object, we can use normal JavaScript property syntax to read and write them. And the code is just as reactive as before.

Astute Readers

If you're wondering why we didn't use an array here, you're ahead of the game! We'll cover reactive arrays in the next lesson.

tsx
export function Counter(): JSX.Element {
return Component(() => {
const counters = reactive.object({
first: 0,
second: 0,
});
 
const total = () => counters.first + counters.second;
 
return () => {
const { first, second } = counters;
 
return (
<>
<pre>
<span>first</span> + <span>second</span> ={" "}
<span>total</span>
</pre>
<pre>
<span>{first}</span> + <span>{second}</span> ={" "}
<span>{total()}</span>
</pre>
<h3 className="count1">first</h3>
<div className="buttons">
<button onClick={() => counters.first++}>
increment
</button>
<button onClick={() => (counters.first = 0)}>
reset
</button>
</div>
<h3 className="count2">second</h3>
<div className="buttons">
<button onClick={() => counters.second++}>
increment
</button>
<button onClick={() => (counters.second = 0)}>
reset
</button>
</div>
</>
);
};
});
}
tsx
export function Counter(): JSX.Element {
return Component(() => {
const counters = reactive.object({
first: 0,
second: 0,
});
 
const total = () => counters.first + counters.second;
 
return () => {
const { first, second } = counters;
 
return (
<>
<pre>
<span>first</span> + <span>second</span> ={" "}
<span>total</span>
</pre>
<pre>
<span>{first}</span> + <span>{second}</span> ={" "}
<span>{total()}</span>
</pre>
<h3 className="count1">first</h3>
<div className="buttons">
<button onClick={() => counters.first++}>
increment
</button>
<button onClick={() => (counters.first = 0)}>
reset
</button>
</div>
<h3 className="count2">second</h3>
<div className="buttons">
<button onClick={() => counters.second++}>
increment
</button>
<button onClick={() => (counters.second = 0)}>
reset
</button>
</div>
</>
);
};
});
}
tsx
export function Counter() {
return Component(() => {
const counters = reactive.object({
first: 0,
second: 0,
});
 
const total = () => counters.first + counters.second;
 
return () => {
const { first, second } = counters;
 
return (
<>
<pre>
<span>first</span> + <span>second</span> ={" "}
<span>total</span>
</pre>
<pre>
<span>{first}</span> + <span>{second}</span> ={" "}
<span>{total()}</span>
</pre>
<h3 className="count1">first</h3>
<div className="buttons">
<button onClick={() => counters.first++}>
increment
</button>
<button onClick={() => (counters.first = 0)}>
reset
</button>
</div>
<h3 className="count2">second</h3>
<div className="buttons">
<button onClick={() => counters.second++}>
increment
</button>
<button onClick={() => (counters.second = 0)}>
reset
</button>
</div>
</>
);
};
});
}
tsx
export function Counter() {
return Component(() => {
const counters = reactive.object({
first: 0,
second: 0,
});
 
const total = () => counters.first + counters.second;
 
return () => {
const { first, second } = counters;
 
return (
<>
<pre>
<span>first</span> + <span>second</span> ={" "}
<span>total</span>
</pre>
<pre>
<span>{first}</span> + <span>{second}</span> ={" "}
<span>{total()}</span>
</pre>
<h3 className="count1">first</h3>
<div className="buttons">
<button onClick={() => counters.first++}>
increment
</button>
<button onClick={() => (counters.first = 0)}>
reset
</button>
</div>
<h3 className="count2">second</h3>
<div className="buttons">
<button onClick={() => counters.second++}>
increment
</button>
<button onClick={() => (counters.second = 0)}>
reset
</button>
</div>
</>
);
};
});
}

Released under the MIT license