2020-02-04 17:02:28 +00:00
|
|
|
# Updux concepts
|
|
|
|
|
2021-10-13 17:54:17 +00:00
|
|
|
## Actions and action generators
|
2020-02-04 17:02:28 +00:00
|
|
|
|
2021-10-13 17:54:17 +00:00
|
|
|
Updux assumes actions following the format
|
|
|
|
|
|
|
|
```js
|
|
|
|
{
|
|
|
|
type: 'theTypeName',
|
|
|
|
payload: {
|
|
|
|
...
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
The important part is having action parameters in the `payload` property. The
|
|
|
|
actions can also have other properties, like `meta`. They are mostly ignored
|
|
|
|
by Updux.
|
|
|
|
|
|
|
|
|
|
|
|
Updux provides an action generator, but you can roll your own if you do wish.
|
|
|
|
All it needs to do to be recognized as an action generator by Updux is
|
|
|
|
|
|
|
|
1. To be a function returning an action (a plain object with at least a
|
|
|
|
`type` property).
|
|
|
|
2. The function also needs to have a `type` property itself.
|
|
|
|
|
|
|
|
|
|
|
|
For example, the following function would work:
|
2020-02-04 17:02:28 +00:00
|
|
|
|
|
|
|
```js
|
|
|
|
function action(type) {
|
|
|
|
return Object.assign( payload => ({type, payload}), { type } )
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2021-10-13 17:54:17 +00:00
|
|
|
### Mutations
|
|
|
|
|
|
|
|
The transformations typically
|
|
|
|
done by a Redux's reducer are called 'mutations' in Updux. A mutation is a
|
|
|
|
function with the following signature:
|
|
|
|
|
|
|
|
```
|
|
|
|
( payload, action ) => state => {
|
|
|
|
// ... stuff done here
|
|
|
|
return new_state;
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
The inversion and chaining of parameters from the usual Redux reducer's
|
|
|
|
signature is there to work with updeep's curried nature. The expansion of
|
|
|
|
the usual `action` into `(payload, action)` is present because in most cases
|
|
|
|
`payload` is what we're interested in. So why not make it easily available?
|
|
|
|
|
|
|
|
### Leftover mutation
|
|
|
|
|
|
|
|
A mutation associated to the special action `+` will match any action that haven't been
|
|
|
|
explicitly dealt with with any other defined mutation.
|
|
|
|
|
|
|
|
```
|
|
|
|
todosUpdux.addMutation( '+', (payload,action) => state => {
|
|
|
|
console.log("hey, action has no mutation! ", action.type);
|
|
|
|
});
|
|
|
|
```
|
|
|
|
|
|
|
|
## Effects
|
2020-02-03 04:45:16 +00:00
|
|
|
|
2020-06-02 20:00:48 +00:00
|
|
|
Updux effects are redux middlewares. I kept that format, and the
|
2020-02-03 04:45:16 +00:00
|
|
|
use of `next` mostly because I wanted to give myself a way to alter
|
|
|
|
actions before they hit the reducer, something that `redux-saga` and
|
|
|
|
`rematch` don't allow.
|
|
|
|
|
|
|
|
An effect has the signature
|
|
|
|
|
|
|
|
```js
|
2020-06-02 20:00:48 +00:00
|
|
|
const effect = ({ getState, dispatch }) => next => action => { ... }
|
2020-02-03 04:45:16 +00:00
|
|
|
```
|
2021-10-13 23:31:37 +00:00
|
|
|
|
|
|
|
|
|
|
|
## Selectors
|
|
|
|
|
|
|
|
Selectors are used to get data derived from the store's state.
|
|
|
|
|
|
|
|
The signature of a selector function is either `(state) => result`
|
|
|
|
or `(state) => (...args) => result`. The selector instances attached
|
|
|
|
to a store's `getState` already do the first call on `state`, so you don't have to.
|
|
|
|
|
|
|
|
```js
|
|
|
|
|
|
|
|
const dux = new Updux({
|
|
|
|
initial: {
|
|
|
|
foo: 1,
|
|
|
|
},
|
|
|
|
selectors: {
|
|
|
|
getFoo: ({foo}) => foo,
|
|
|
|
getFooPlus: ({foo}) => increment => foo + increment,
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
console.log(dux.selectors.getFoo({foo: 2})); // prints 2
|
|
|
|
console.log(dux.selectors.getFooPlus({foo: 2})(3)); // prints 5
|
|
|
|
|
|
|
|
const store = dux.createStore();
|
|
|
|
|
|
|
|
console.log(store.selectors.getFoo({foo: 2})); // prints 2
|
|
|
|
console.log(store.selectors.getFooPlus({foo: 2})(3)); // prints 5
|
|
|
|
|
|
|
|
console.log(store.getState.getFoo()); // prints 2
|
|
|
|
console.log(store.getState.getFooPlus(3)); // prints 5
|
|
|
|
|
|
|
|
```
|