Skip to content

Instantly share code, notes, and snippets.

@buzinas
Last active September 30, 2016 18:21
Show Gist options
  • Save buzinas/770ae581d7f8aa5c5d8f2d02b01cbe66 to your computer and use it in GitHub Desktop.
Save buzinas/770ae581d7f8aa5c5d8f2d02b01cbe66 to your computer and use it in GitHub Desktop.
Redux without the switch clauses (obviously this is only a draft)
const role = { role: 'menu' };
export const activateItem = { ...role, cmd: 'activateItem' };
export const toggle = { ...role, cmd: 'toggle' };
export const activateMenuItem = (item) => ({
...activateItem,
payload: item
});
export const toggleMenu = () => ({
...toggle
});
import Inferno from 'inferno';
import ButtonMenu from './button-menu';
import Menu from './menu';
export default function App() {
return (
<div>
<ButtonMenu />
<Menu />
</div>
);
}
import Inferno from 'inferno';
import { connect } from 'inferno-redux';
import { toggleMenu } from '../actions/menu';
function ButtonMenu({ toggle }) {
return (
<button onclick={toggle}>
Toggle menu
</button>
);
}
export default connect(
f => f,
dispatch => ({ toggle: dispatch(toggleMenu()) })
)(ButtonMenu);
import Inferno from 'inferno';
import { connect } from 'inferno-redux';
import { activateMenuItem } from '../actions/menu';
function MenuItem({ dispatch, active, activate }) {
const classList = ['menu__item'];
if (active) {
classList.push('menu__item--active');
}
return (
<div onclick={activate} className={classList.join(' ')}>
{children}
</div>
);
}
export default connect(
(state, ownProps) => ({ active: state.menu.activeItem === ownProps.children }),
(dispatch, ownProps) => ({ activate: () => dispatch(activateMenuItem(ownProps.children)) })
)(MenuItem);
import Inferno from 'inferno';
import MenuItem from './menu-item';
function Menu({ open }) {
return (
<nav>
{ open && ['Articles', 'About', 'Subscribe'].map(item => <MenuItem>{item}</MenuItem>) }
</nav>
);
}
export default connect(
state => ({ open: state.menu.open })
)(Menu);
import Inferno from 'inferno';
import { Provider } from 'inferno-redux';
import App from './app';
export function Root({ store }) {
return (
<Provider store={store}>
<App />
</Provider>
);
}
import { createStore } from 'redux';
export function configureStore(initialState, ...reducers) {
const store = createStore(initialState, ...reducers);
return store;
}
import Inferno from 'inferno';
import { render } from 'inferno-dom';
import { configureStore } from './configure-store';
import { initialState, reducers } from './reducers';
import { Root } from './components/root';
const store = configureStore(initialState, ...reducers);
render(<Root store={store} />, document.getElementById('main'));
import { menuInitialState, menuReducers } from './menu';
export const initialState = {
menu: menuInitialState
};
export reducers = [
...menuReducers
];
import { activateItem, open } from '../actions/menu';
export const menuInitialState = {
activeItem: 'Articles',
open: false
};
export const menuReducers = [
{ ...activateItem, reducer: (state, action) => ({ ...state, activeItem: action.payload }) },
{ ...open, reducer: (state, action) => ({ ...state, open: !state.open }) }
];
export function createStore(initialState, ...reducers) {
let state = initialState;
const reducers = createReducers();
const store = {
getState() {
return state;
},
dispatch(action) {
reducers.execute(action);
return this;
},
addReducer(reducer, cb) {
reducers.add(reducer);
return this;
},
addReducers(...reducers) {
reducers.forEach(this.addReducer);
return this;
}
};
store.addReducers(...reducers);
return store;
// ---
function createReducers() {
const reducers = [];
return {
add(reducer) {
reducers.push(reducer);
return this;
},
execute(action) {
reducers
.filter(r => r.role === action.role && r.cmd === action.cmd)
.forEach(r => state = ({ ...state, [action.role]: r.reducer.call(null, state[action.role], action) }));
}
};
}
}
@buzinas
Copy link
Author

buzinas commented Sep 30, 2016

Heavily inspired by Redux and Seneca, the idea is to use reducers but without the switch boilerplate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment