Skip to content

Instantly share code, notes, and snippets.

@vitalipe
Last active December 11, 2017 13:35
Show Gist options
  • Select an option

  • Save vitalipe/80981310ecacfa88ccd3238d2535b31a to your computer and use it in GitHub Desktop.

Select an option

Save vitalipe/80981310ecacfa88ccd3238d2535b31a to your computer and use it in GitHub Desktop.
just goofing around with stateful function components
// implementation details here, you want to look at the other files first
function init(React) {
let createElement = React.createElement;
let _cache = new WeakMap(); // can also be a regular map..
let _currentElement = null; // this is where updateState will lookup the current state
let createWrapper = (fn) =>
class StateWrapper extends React.Component {
constructor(props) {
super(props)
this.state = {};
}
render() {
_currentElement = this;
return fn(this.props, this.state);
}
}
// works like setState, but you can also pass a key.. (I'm too lazy to implement a recursive path)
let updateState = (key, updater) => {
let current = _currentElement;
if (!updater)
[key, updater] = [updater, key];
if (key)
return () =>
current.setState((prv, props) => ({[key]: updater(prv[key], props)}));
return () => current.setState(updater);
}
// updateState shortcut for boolean values
let toggleState = (key) => updateState(key, v => !v);
// create React hook
React.createElement = (e, ...rest) => {
if (typeof e !== "function" || e.isReactComponent)
return createElement.apply(React, [e, ...rest]);
if (!_cache.has(e))
_cache.set(e, createWrapper(e));
return createElement(_cache.get(e), ...rest);
}
// export
return {updateState, toggleState};
};
const Counter = ({name}, {count = 0}) =>
<button onClick={updateState("count", (c = 0) => c+1)}>{name} was clicked {count} times!</button>
// vanilla react
class Counter extends React.Component {
constructor(props) {
super(props)
this.state = {count: 0};
}
render() {
return <button
onClick={() => this.setState(({count}) => {count: count+1})}>
{this.props.name} was clicked {this.state.count} times!
</button>
}
}
// react + mobx
@observer class Counter extends React.Component {
@observable count = 0;
render() {
return <button onClick={() => this.count++}>{this.props.name} was clicked {this.count} times!</button>
}
}
@benjamingr
Copy link

benjamingr commented Dec 11, 2017

// once
const observer = (state, fn) => @mobxReact.observer class extends React.Component {
  @mobx.observable state = state;
  render() { return fn(this.props, this.state); }
}

// example
const Counter = observer({count: 1}, ({name}, s) => <button onClick={() => s.count++}>{name} was clicked {s.count} times! </button>);

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