Build Yourself a Redux (thunk middleware)
This sample code goes along with a Zapier engineering blog post that walks you through building a mini version of redux and react-redux.
by justindeal
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.js"></script>
<script src="https://npmcdn.com/[email protected]/dist/react-with-addons.js"></script>
<script src="https://npmcdn.com/[email protected]/dist/react-dom.js"></script>
<div id="root"></div>
CSS
body {
font-family: sans-serif;
font-size: 14px;
}
.editor-button {
border: gray solid 1px;
background-color: white;
min-width: 100px;
font-size: 14px;
border-radius: 3px;
}
.note-list {
list-style: none;
padding: 0px;
}
.note-list-item {
font-size: 14px;
margin-bottom: 5px;
}
.editor-content {
font-size: 14px;
margin: 10px 0px 14px;
vertical-align: bottom;
width: 90vw;
height: 50vh;
}
Babel + JSX
///////////////////////////////
// Mini Redux implementation //
///////////////////////////////
const validateAction = action => {
if (!action || typeof action !== 'object' || Array.isArray(action)) {
throw new Error('Action must be an object!');
}
if (typeof action.type === 'undefined') {
throw new Error('Action must have a type!');
}
};
const createStore = (reducer, middleware) => {
let state;
const subscribers = [];
const coreDispatch = action => {
validateAction(action);
state = reducer(state, action);
subscribers.forEach(handler => handler());
};
const getState = () => state;
const store = {
dispatch: coreDispatch,
getState,
subscribe: handler => {
subscribers.push(handler);
return () => {
const index = subscribers.indexOf(handler);
if (index > 0) {
subscribers.splice(index, 1);
}
};
}
};
if (middleware) {
const dispatch = action => store.dispatch(action);
store.dispatch = middleware({
dispatch,
getState
})(coreDispatch);
}
coreDispatch({type: '@@redux/INIT'});
return store;
};
const applyMiddleware = (...middlewares) => store => {
if (middlewares.length === 0) {
return dispatch => dispatch;
}
if (middlewares.length === 1) {
return middlewares[0](store);
}
const boundMiddlewares = middlewares.map(middleware =>
middleware(store)
);
return boundMiddlewares.reduce((a, b) =>
next => a(b(next))
);
};
const thunkMiddleware = ({dispatch, getState}) => next => action => {
if (typeof action === 'function') {
return action(dispatch, getState);
}
return next(action);
};
const loggingMiddleware = ({getState}) => next => action => {
console.info('before', getState());
console.info('action', action);
const result = next(action);
console.info('after', getState());
return result;
};
/////////////////////////////////////
// Mini React Redux implementation...