Skip to content

Instantly share code, notes, and snippets.

@elierotenberg
Last active March 3, 2016 23:41
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save elierotenberg/91c7d7f853a44673ea68 to your computer and use it in GitHub Desktop.
Save elierotenberg/91c7d7f853a44673ea68 to your computer and use it in GitHub Desktop.
Generator function as a stateful component
const willUnmount = Symbol('unmount');
function statefulComponent(getInitialState, render, componentWillUnmount = () => void 0) {
return function*(props) {
const internalId = React.pleaseGiveMeAnInternalId();
const state = getInitialState(props);
const setState = (nextState) => {
Object.assign(state, nextState);
React.pleaseRerenderThisInternalId(internalId);
};
let nextProps = props;
do {
nextProps = (yield render(nextProps, state, setState)) || nextProps;
} while(nextProps !== willUnmount);
return componentWillUnmount(state);
}
}
const Counter = statefulComponent(
() => ({ times: 0 }),
({ label }, { times }, setState) =>
<button onClick={() => setState({ times: times + 1 })}>
Clicked {times} times on button {label}
</button>
);
const counter = Counter({ label: 'label A' });
counter.next().value; // 'render'
counter.next().value; // 'render'
counter.next({ label: 'label B' }).value; // 'setProps & rerender'
counter.next(willUnmount); // 'componentWillUnmount'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment