REDUX
REDUCER
//Pure function that takes in state and an action and returns new state.
const secret = function (state = {value: 'Default State Value'}, action) {
fireZeMissiles();
//return the action text or a default value
switch (action.type) {
case 'SET_TEXT':
return action.text;
case 'RESET_TEXT':
return '';
case 'CONCATENATE_TEXT':
return state + ', ' + action.text;
default:
return state;
}
}
fireZeMissiles () => destroysTheWorld();CREATE STORE
- getState
- dispatch
- subscribe
const createStore = function (reducer) {
//declare state and initialize listeners
let state;
let listeners = [];
//getState simply returns state
const getState = () => state;
const dispatch = (action) => {
//on dispatch the reducer is called with state and action
state = reducer(state, action);
//then the listeners are each executed
listeners.forEach(listener => listener());
};
const subscribe = (listener) => {
//on subscription the listener is added to the listeners array
listeners.push(listener);
//subscribe then returns a function that removes the listener
//to be used as unsubscribe later
return () => {
listeners = listeners.filter(l => l !== listener)
};
};
//forces the reducer to return intial value
dispatch({});
return { getState, dispatch, subscribe }
}VANILLA REDUX EXAMPLE TIME
REACT-REDUX
VANILLA REDUX WITH REACT EXAMPLE
REACT REDUX
PROVIDER
class Provider extends Component {
getChildContext() {
return {
store: this.props.store
};
}
render () {
return this.props.children
}
}
Provider.childContextTypes = {
secretStore: React.PropTypes.object
};
//used like:
const render = () => (
<Provider>
<ComponentOne />
<ComponentTwo />
</Provide>
);
const ComponentOne = (props, { secretStore }) => {
let input;
return (
<div>
//Do stuff with props and store
</div>
)
};
AddSecret.contextTypes = {
secretStore: React.PropTypes.object
};
CONNECT
//Pure function that takes in state and an action and returns new state.
const mapDispatchToProps = dispatch => {
return {
onRateSecretClick: (secretId, rating) => {
dispatch({
type: 'RATE_SECRET',
payload: { secretId, rating }
});
}
}
};
const mapStateToProps = state => {
return { listOfThings: getFiltered(state.things, state.filter) }
};
const ContainerComponent = connect(
mapStateToProps,
mapDispatchToProps
)(ListOfThingsComponent);
//Note if you don't pass either arg, you get a plain ref to dispatchREACT-REDUX EXAMPLE
TIME TRAVEL
{
state: {
past: [],
present: 0,
future: []
}
}
{
state: {
past: [0],
present: 1,
future: []
}
}
{
state: {
past: [0,1,2,3,4,5],
present: 6,
future: []
}
}
{
state: {
past: [0,1,2,3,4],
present: 5,
future: [6]
}
}function undoable(reducer) {
// Call the reducer with empty action to populate the initial state
const initialState = {
past: [],
present: reducer(undefined, {}),
future: []
}
// Return a reducer that handles undo and redo
return function (state = initialState, action) {
const { past, present, future } = state
switch (action.type) {
case 'UNDO':
const previous = past[past.length - 1]
const newPast = past.slice(0, past.length - 1)
return {
past: newPast,
present: previous,
future: [ present, ...future ]
}
case 'REDO':
const next = future[0]
const newFuture = future.slice(1)
return {
past: [ ...past, present ],
present: next,
future: newFuture
}
default:
// Delegate handling the action to the passed reducer
const newPresent = reducer(present, action)
if (present === newPresent) {
return state
}
return {
past: [ ...past, present ],
present: newPresent,
future: []
}
}
}
}REACT REDUX UNDOABLE EXAMPLE
REDUX
By Ryan Moore
REDUX
- 483