Skip to content

Instantly share code, notes, and snippets.

@dburles
Created May 2, 2019 23:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dburles/5dd694fce578368854e46b51221fae6c to your computer and use it in GitHub Desktop.
Save dburles/5dd694fce578368854e46b51221fae6c to your computer and use it in GitHub Desktop.
import React, { memo, useEffect, useState } from 'react';
export default function State(initialState, setterHandler = value => value) {
const subscriptions = [];
let shouldUpdate = true;
let state = initialState;
function subscribe(fn) {
subscriptions.push(fn);
return function() {
subscriptions.splice(subscriptions.indexOf(fn), 1);
};
}
const wrapped = () => WrappedComponent => {
return memo(
function TinyStateComponent(props) {
const [, setState] = useState();
useEffect(() => {
return subscribe(() => setState({}));
}, []);
return React.createElement(WrappedComponent, props);
},
function shouldComponentUpdate(props, nextProps) {
return nextProps !== props || shouldUpdate;
},
);
};
function get() {
return state;
}
function set(setValue, cb) {
const newValue =
typeof setValue === 'function' ? setValue(state) : setValue;
if (newValue !== state) {
state = setterHandler(newValue);
shouldUpdate = true;
subscriptions.forEach(fn => fn(cb));
} else {
shouldUpdate = false;
}
}
wrapped.get = get;
wrapped.set = set;
wrapped.subscribe = subscribe;
return wrapped;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment