Overview
Why Hooks?
Hooks enable us to implement components in a reactive way, keeping connected logic co-located. They were initially introduced by React and soon adopted by Melody.
A first glimpse
useState
is one of the hooks that are provided by the melody-hooks
package. It accepts an initial state and returns a tuple of the current value and a mutator function.
In Melody, the function that you pass to createComponent
is a hook itself and is therefore also prefixed with the word use
. We call this function the components state hook. This particular feature of Melody can't be stressed enough because it is what enables even more composition and code reuse to happen.
The State Hook
The primary Hook of a component is called the State Hook in Melody. Effectively the State Hook is a function which maps the props to the template context while being able to access additional Hooks to persistently store state, register effects and more.
Understanding the execution flow
How does all of this work? Why does it look so magical? In general using Hooks and building custom hooks is a lot easier than understand how they work. It's still worth understanding how they fit into a reactive programming world like Melody.
When the component is mounted, Melody will execute the state hook function. This will trigger useState(0)
to be executed. Since it is the first time and no other value has ever been specified for this hook, useState
will return a tuple of the current value, 0
, and a function that can be used to change the value - the mutator. Thus, the variable count
in the example above will contain the value 0
.
We also define a few more functions to increase or decrease the counter by 1 and return all of them together as an object. This object will be the context in which our template is executed.
Now, if the user clicks on the +
button, setCount(count + 1)
will be executed. That changes count
to 1
. Melody will notice this change and will cause the state hook to be evaluated again.
This time, however, the invocation of useState(0)
will return 1
, since that's the current state of the hook. Melody kept track of the value stored through the hook during distinct executions of the state hook function.
Composing hooks
One of the things that makes hooks a perfect match for Melody is that we don't need anything except a hook and a template to create a working Melody component. Even the function which maps properties to a state is just a hook.
This enables powerful composition and increases reusability. Let's explore how that works.
Assume, for a moment, that you'd like to make a component selectable. We can achieve that objective by using the useState
hook with a boolean
value. In order to keep the logic of toggling the selected state local, we can expose a toggle function instead of the plain mutator function.
Now imagine that in addition to being selectable we also want to have a counter. One way to achieve that would be to put all of the logic into a single state hook, however, that wouldn't really help with readability. Instead, we can combine the useCounterState
hook with the useSelectable
hook to create a new one.
Each state hook on its own is a useful component. But you can also combine them to create more complex components.
Let's take things one step further and say that we want to create a component that is selectable, feature a counter mechanism but freezes the counter if it is not selected.
In this example we've composed a new behaviour out of two already existing behaviours while also modifying their behaviour.
While this is already extremely powerful, the above example could have been implemented in a cleaner way. We already had the composition of countable and selectable and all we really wanted to do was to refine how they work.
With that in mind, let's improve our implementation.
This type of hook is usually referred to as a decorator hook since it decorates another hook, changing its behaviour but not its public API.
Last updated
Was this helpful?