Skip to content

Instantly share code, notes, and snippets.

@jmas
Created January 9, 2018 15:07
Show Gist options
  • Save jmas/c5c813d14178ef093a6da0fa0c658aa4 to your computer and use it in GitHub Desktop.
Save jmas/c5c813d14178ef093a6da0fa0c658aa4 to your computer and use it in GitHub Desktop.
const withState = ({
initialState={},
actions={},
handleBeforeAction=null,
handleAfterAction=null,
}) => Component => (
class extends PureComponent {
state = initalState,
render() {
const afterAction = (newState, actionName, args) => {
if (handleAfterAction) {
handleAfterAction(newState, actionName, args);
}
this.setState(() => newState);
};
return (
<Component
{...state}
actions={Object.keys(actions).reduce((nextActions, name) => ({
...nextActions,
[name]: (...args) => {
if (handleBeforeAction) {
handleBeforeAction(state, name, args);
}
const newState = actions[name](..args, state);
if (newState instanceof Promise) {
newState.then(newState => afterAction(newState, name, args));
} else if (newState) {
afterAction(newState, name, args);
}
}
}), {})}
/>
);
}
}
);
withState({
initalState: {
counter: 0,
},
actions: {
increment(n, state) {
return {
...state,
counter: state.counter + n,
};
},
decrement(n, state) {
return {
...state,
counter: state.counter - n,
};
},
slowIncrement(n, state) {
return new Promise(resolve => {
setTimeout(() => {
resolve({
...state,
counter: state.counter + n,
});
}, 1000);
});
},
},
handleBeforeAction(state, actionName, args) {
console.info(`[${actionName}]`, args, state);
},
handleAfterAction(state, actionName, args) {
console.info(`[${actionName}]`, args, state);
},
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment