I. Flux
4 parts of Flux architecture:
- View
- Actions
- Dispatcher
- Store
Relationship
- Store: model object managing all data; has updating methods as well
- provide data to View
- provide updating methods to Actions
- Dispatcher: extends
Event Emitter object
- used by component to register event & callbacks
- used by component to emit actions to call store updating methods
- View: receive data from store
- Actions: used by component to let dispather emit actions
- Great article: http://www.ruanyifeng.com/blog/2016/01/flux.html
- Store: model object managing all data; has updating methods as well
II. Redux
store
getState()
: source of datadispath()
: emit actions, execute reducer to update statesubscribe()
: component subscribe to receive updated state
reducer
- like
emitter.on
, used to register all the updating functions for related actions - pure function
combineReducers()
: used to make logic clean
- like
Store implementation
How to use the
store
object1
2
3
4
5
6
7import { createStore } from 'redux';
let { subscribe, dispatch, getState } = createStore(reducer);
// or
let store = createStore(todoApp, window.STATE_FROM_SERVER)
store.getState()
store.dispatch()
store.subscribe()redux provide an interface
createStore()
to create thestore
object1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22const createStore = (reducer) => {
let state;
let listeners = [];
const getState = () => state;
const dispatch = (action) => {
state = reducer(state, action);
listeners.forEach(listener => listener());
};
const subscribe = (listener) => {
listeners.push(listener);
return () => {
listeners = listeners.filter(l => l !== listener);
}
};
dispatch({});
return { getState, dispatch, subscribe };
};
An example using Redux
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31const Counter = ({ value, onIncrement, onDecrement }) => (
<div>
<h1>{value}</h1>
<button onClick={onIncrement}>+</button>
<button onClick={onDecrement}>-</button>
</div>
);
const reducer = (state = 0, action) => {
switch (action.type) {
case 'INCREMENT': return state + 1;
case 'DECREMENT': return state - 1;
default: return state;
}
};
const store = createStore(reducer);
const render = () => {
ReactDOM.render(
<Counter
value={store.getState()}
onIncrement={() => store.dispatch({type: 'INCREMENT'})}
onDecrement={() => store.dispatch({type: 'DECREMENT'})}
/>,
document.getElementById('root')
);
};
render();
store.subscribe(render);
III. React-Redux package
connect()
:- connect UI component with it outer Controller component
- usage:
const Contrainer = connect(mapStateToprops, mapDispatchToProps)(UIComponent)
mapStateToProps()
- map
state
in Redux store to UI - like
eventEmitter.subscribe()
, will always get the updated state from Redux
- map
mapDispatchToProps
- map
actions dispatch()
in Redux to UI - like
eventEmitter.emit()
, will trigger actions when UI event is fired, to execute reducer to update the state
- map
<Provider>
component- an outer container, used to pass the
state
to inner components - using
context
attribute
- an outer container, used to pass the