In the previous lesson, Streams, we started setting up the Meiosis pattern:
update
stream of patchesstates
stream of states, obtained with scan
on the update
stream and applying
an accumulatoractions
object containing functions to which we pass update
, so that those functions can
trigger state changes.Our state had the following shape:
{
value: 0
}
Our patches were numbers such as 1
and -1
, and our accumulator applied the patches to the state
by adding the number to state.value
.
We are going to change our patches and accumulator function to be general-purpose, so that the shape of our state can be much more flexible, and our actions can issue patches to make all sorts of changes to the state.
Let's build a temperature example with the following initial state:
const initial = {
temperature: {
value: 22,
units: 'C'
}
};
We can increase and decrease the value, as well as change the units betwen C
(Celsius) and F
(Farenheit), converting the value in the process.
We need to:
In this section, we will use one approach using function patches. In the next section, we will look at another approach - my personal favourite - using a small utility called Mergerino.
Instead of using plain numbers as patches, which are limited to incrementing a counter, we can use
functions. Indeed, we can pass functions onto the update
stream and use them in the
accumulator to update the state.
These functions receive the current state as a parameter, and return the updated state. For example, to increment the temperature value:
const actions = {
increment: (update, amount) => {
update((state) => ({
temperature: {
value: state.temperature.value + amount,
units: state.temperature.units
}
}));
}
};
Note that we could also use a library to update the state, such as lodash/fp or Ramda for example.
Now we need to use function patches in the accumulator function. Remember that the accumulator gets, as parameters, the current state and the incoming patch. The accumulator must return the updated state. Since the incoming patches are functions, we just need to call them:
const states = flyd.scan(
(state, patch) => patch(state),
initial,
update
);
Putting it all together, we have:
Try it out: notice that the initial state appears in the output on the right. Within the console, type and then press Enter:
actions.increment(update, 2)
actions.changeUnits(update)
In the output on the right, you'll see the updated states.
In the next section, we will look at an alternative to function patches, called Mergerino.