Minimal Redux w/o React

by eigenjoy

HTML

<script src="https://fb.me/react-0.14.7.min.js"></script>
<script src="https://fb.me/react-dom-0.14.7.min.js"></script>
<div id='root'>
</div>

Babel + JSX

const createStore = (reducer) => {
  let state;
  let listeners = [];

  const getState = () => state;

  const dispatch = (action) => {
    console.log("DISPATCH");
    state = reducer(state, action);
    console.log("New state!")
    console.log(state)
    listeners.forEach(listener => listener());
  };

  const subscribe = (listener) => {
    listeners.push(listener);
    return () => {
      listeners = listeners.filter(l => l !== listener);
    }
  };

  dispatch({}); // dummy dispatch

  return { getState, dispatch, subscribe };
};

let reducer = (state = {
  messages: [],
}, action) => {
  let currentId = 0;
  switch (action.type) {
  case 'ADD_MESSAGE':
    return {
      messages: state.messages.concat({
         message: action.message, 
         id: currentId++
      })
    }
    default: 
      return state;
  }
}

let store = createStore(reducer);

const MessageView = (props) => (
  <ul>
    {props.messages.map(m => (
      <li>{m}</li>
    ))}
  </ul>
)

const MessageInput = React.createClass({
  render: function () {
    return(
      <div>
        <input ref='messageInput'></input>
        <button onClick={() =>
           store.dispatch({
             type: 'ADD_MESSAGE',
             message: this.refs.messageInput.value,
           })
         }>Submit</button>
       </div>
    )
  },
});

const App = (props) => (
  <div>
    <MessageView messages={props.messages} />
    <MessageInput />
  </div>
)

const render = () => {
  ReactDOM.render(
    <App />,
    document.getElementById('root')
  );
};

store.subscribe(render);
render();