Here will be a top to bottom question and answer for HAv2!
How does a simple counter app look in V2?
app({
init: 0,
view: state => (
<main>
<h1>{state}</h1>
<button onclick={state => state - 1}>-</button>
<button onclick={state => state + 1}>+</button>
</main>
),
container: document.body
})
Ok so the action signature looks different now doesn't it?
state => newState
No longer do we have to curry: obj => (state, actions) => ({ mergeKey: 'mergeValue' });
Let's start with the most basic form of an action:
// state
const state = {
num,
};
...
// actions
export const Add = state => ({ num: state.num + 1 });
Ok that's easy enough. You said there are other "forms"? What's the next evolution?
const state = {
title: '',
num: 0,
};
// grab input value from an event
export const Title = (state, event) => ({ ...state, title: event.target.value.trim() });
<input oninput={Title} />
// grab prop passed into action directly
export const ChangeNum = (state, props) => ({ ...state, num: props.num });
<button onclick={{ action: ChangeNum, { num: 1 } }}>Change Num to 1</button>
Ok that's interesting, if I want to pass a value directly I have to specify an object.
That object needs a key action
and a value of the action I want to call?
Yea, while it adds some "boilerplate", it makes life easier in the future.
A little work pays off π
Effects are a way of sending off a Promise or some sort of impure function to a factory that will have a worker process your request.
This is the signature of an acction that needs to call an effect:
const Action = state => [state, theEffect]
Essentially you can update some state prior to sending off the Effect to be processed.
In order for HAv2 to understand that you want an effect an array of elements needs to be returned.
The first element is the state (unchaged or changed), and the second is the Effect that needs to be called.
So what does an effects signature look like?
Let's take a get request as an example:
// HELP! Unclear if props includes both state and actions?
const Effect = (props, dispatch) => {
axios.get('/api/users/${props.userId}')
.then({ data }) => {
dispatch(props.Success, data);
})
.catch((err) => {
dispatch(props.Failed, err);
});
}
An effect has the luxury of being able to call the dispatch
function directly.
Essentially the factory sends the effect through, a worker adds props and dispatch to your effect and then HAv2 calls the Effect π!
Once the effect calls dispatch that effect has been processed and the patch algo gets triggered for the VDOM to do it's thing π
So the lifecycle of getting an effect to process an update looks like so: action -> effect -> dispatch