https://github.com/atellmer/spawn-x-effects
Cascading state updates for spawn-x
https://github.com/atellmer/spawn-x-effects
angular effect flux javascript mobx observer react reactive redux saga state store zone
Last synced: 8 months ago
JSON representation
Cascading state updates for spawn-x
- Host: GitHub
- URL: https://github.com/atellmer/spawn-x-effects
- Owner: atellmer
- License: mit
- Created: 2017-03-16T08:35:55.000Z (over 8 years ago)
- Default Branch: master
- Last Pushed: 2017-03-17T09:44:11.000Z (over 8 years ago)
- Last Synced: 2025-03-08T13:39:37.475Z (9 months ago)
- Topics: angular, effect, flux, javascript, mobx, observer, react, reactive, redux, saga, state, store, zone
- Language: JavaScript
- Homepage:
- Size: 32.2 KB
- Stars: 1
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# spawn-x-effects
### Interceptor (middleware) for [spawn-x](https://github.com/atellmer/spawn-x).
Effects is a small interceptor that enables make cascading state updates, when one action initialize many other actions.
## install
With npm:
```
npm install spawn-x spawn-x-effects --save
```
With yarn:
```
yarn add spawn-x spawn-x-effects
```
With bower:
```
bower install spawn-x spawn-x-effects --save
```
```html
```
## Usage
#### app/store/index.js
```javascript
import { createStore, addInterceptor } from 'spawn-x';
import { effects } from 'spawn-x-effects';
import { logger } from '../interceptors/logger';
import { tracksEffect } from '../effects/tracks';
import { renderEffect } from '../effects/render';
const initialState = {
tracks: [
'Puddle Of Mudd - Control',
'American Hi-Fi - Flavor Of The Weak',
'SR-71 - What A Mess'
]
}
//inject effects interceptor
const store = createStore(
initialState,
addInterceptor(logger, effects)
);
//add effect into effects interceptor
effects.run(tracksEffect);
effects.run(renderEffect);
export {
store
}
```
### Effect is just a function which accept store and action and then updates state
#### app/effects/tracks.js
```javascript
import {
ADD_TRACK,
UPDATE_STORE_INIT,
UPDATE_STORE,
UPDATE_STORE_COMPLETE,
NEED_RENDER
} from '../constants';
const tracksEffect = (store, action) => {
switch (action.type) {
case ADD_TRACK: {
store.update('', {
type: UPDATE_STORE_INIT,
data: null
});
store.update('tracks', {
type: UPDATE_STORE,
data: store.select('tracks') ? store.select('tracks').concat(action.data) : [].concat(action.data)
});
store.update('', {
type: UPDATE_STORE_COMPLETE,
data: null
});
store.update('', {
type: NEED_RENDER,
data: {
render: store.select('tracks')
}
});
break;
}
}
}
export {
tracksEffect
}
```
#### app/effects/render.js
```javascript
import {
NEED_RENDER,
RENDER_INIT,
RENDER_COMPLETE
} from '../constants';
import { render } from '../methods/render';
const renderEffect = (store, action) => {
switch (action.type) {
case NEED_RENDER: {
store.update('', {
type: RENDER_INIT,
data: null
});
render(action.data.render);
store.update('', {
type: RENDER_COMPLETE,
data: null
});
break;
}
}
}
export {
renderEffect
}
```
#### app/actions/tracks.js
```javascript
import { store } from '../store';
import { ADD_TRACK } from '../constants';
const addTrack = data => {
store.update('', {
type: ADD_TRACK,
data: data
});
}
export {
addTrack
}
```
### And other files...
#### app/constants/index.js
```javascript
export const ADD_TRACK = 'ADD_TRACK';
export const UPDATE_STORE_INIT = 'UPDATE_STORE_INIT';
export const UPDATE_STORE = 'UPDATE_STORE';
export const UPDATE_STORE_COMPLETE = 'UPDATE_STORE_COMPLETE';
export const NEED_RENDER = 'NEED_RENDER';
export const RENDER_INIT = 'RENDER_INIT';
export const RENDER_COMPLETE = 'RENDER_COMPLETE';
```
#### app/methods/render.js
```javascript
const render = tracks => {
const list = document.querySelector('#trackList');
list.innerHTML = '';
if (tracks === null) tracks = [];
tracks.forEach(item => {
const li = document.createElement('li');
li.textContent = item;
list.appendChild(li);
});
}
export {
render
}
```
#### app/interceptors/logger.js
```javascript
function logger(store) {
return next => action => {
console.log('action: ', action.type + ': ', JSON.parse(JSON.stringify(action.data)));
next(action);
}
}
export {
logger
}
```
#### app/index.js
```javascript
import '../index.html';
import { store } from './store';
import { render } from './methods/render';
import { addTrack } from './actions/tracks';
const btn = document.querySelector('#addTrack');
const input = document.querySelector('#input');
btn.addEventListener('click', () => {
addTrack(input.value);
input.value = '';
});
render(store.select('tracks'));
```
#### index.html
```html
App
Add track
```
## LICENSE
MIT © [Alex Plex](https://github.com/atellmer)