The bau.state
function create a reactive state thanks the Javascript Proxy feature.
The idea is to intercept data mutations and update the DOM accordingly.
For Vue developers,
bau.state
is equivalent to ref
const myBoolState = bau.state(false);
const myNumberState = bau.state(1);
const myStringState = bau.state("foo");
const myArrayState = bau.state(["foo", "bar"]);
const myObjetState = bau.state({ name: "Freddy", rank: 2 });
The value is read and written with the val
key.
const myStringState = bau.state("foo");
// Read
console.log(myStringState.val); // "foo"
// Write
myStringState.val = "bar";
// Read
console.log(myStringState.val); // "bar"
See the dedicated documentation for arrays
const myObjetState = bau.state({ score: 0, rank: 2 });
// Read
console.log(myObjetState.val.rank); // 2
// Write
myObjetState.val.ranks = 3;
// Read
console.log(myObjetState.val.rank); // 3
When mutating a bunch of values, it is more efficient to use the bau.batch to gather all the data mutations, then render only once, and recompute the eventual derivation functions only once
const myDerivedState = bau.derive(() => expensiveComutation(myObjetState.val));
const onclick = () => {
bau.batch(() => {
cardState.val.score = 10;
cardState.val.rank = 3;
});
};
When a state with primitive value is inside a element, it is automatically reactive:
counterState holds an integer and is placed inside a div.
const TestReactiveStateNumber = () => {
const counterState = bau.state(0);
return article(
h1("State Number"),
button({ onclick: () => counterState.val++ }, "Increment"),
div(counterState)
);
};
messageState holds a string and is placed inside a span. When the button is clicked, the messageState value is mutated, the message in the span is automatically updated.
const TestReactiveStateString = () => {
const messageState = bau.state("Ciao");
return article(
h1("State String"),
button(
{ onclick: () => (messageState.val = `${messageState.val} Bello`) },
"Add Bello"
),
span(messageState)
);
};
Functions can be placed inside the element tree, the state dependencies are collected automatically, later on, when one of these states it mutated, the function is executed and return a new element.
const TestReactiveFunction = () => {
const showState = bau.state(true);
return article(
h1("Reactive Function"),
button(
//
{ onclick: () => (showState.val = !showState.val) },
() => (showState.val ? "HIDE" : "SHOW")
),
() => showState.val && "Stuff to show"
);
};
The style property can be reactive by assigning a function to the style property:
const TestReactiveStyle = () => {
const colorState = bau.state(false);
return article(
h1("Reative style"),
div(
{
style: () => (colorState.val ? "color:red;" : ""),
},
button(
{ onclick: () => (colorState.val = !colorState.val) },
"Click to change the style"
),
p("My Text")
)
);
};
The class property can be reactive by assigning a function to the class property. First define a class in your css file:
// your css file
.active {
color: green;
border-bottom: 2px dashed green;
}
When the button is clicked, the class will toogle from empty to active.
// Your js file
const TestReactiveClass = () => {
const colorState = bau.state(false);
return article(
h1("Reative class"),
div(
{
class: () => (colorState.val ? "active" : ""),
},
button(
{ onclick: () => (colorState.val = !colorState.val) },
"Click to change the style"
),
p("My Text")
)
);
};