react-unistore
Version:
778b connector between React and unistore
101 lines • 3.59 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const react_1 = require("react");
function mapActions(actions, store) {
if (typeof actions === "function") {
actions = actions(store);
}
const mapped = {};
for (const i in actions) {
mapped[i] = store.action(actions[i]);
}
return mapped;
}
exports.mapActions = mapActions;
function select(properties) {
if (typeof properties === "string") {
properties = properties.split(/\s*,\s*/);
}
return (state) => {
const selected = {};
for (let i = 0; i < properties.length; i++) {
selected[properties[i]] = state[properties[i]];
}
return selected;
};
}
exports.select = select;
const UnistoreContext = react_1.createContext(null);
exports.Provider = UnistoreContext.Provider;
exports.useStore = () => {
const store = react_1.useContext(UnistoreContext);
if (!store) {
throw new Error("Missing context. Ensure you've rendered a Provider.");
}
return store;
};
exports.useAction = (action) => exports.useStore().action(action);
exports.useSelector = (selector, equalityFn) => {
const store = exports.useStore();
const [, forceUpdate] = react_1.useReducer(x => x + 1, 0);
const resultRef = react_1.useRef(null);
resultRef.current = selector(store.getState());
react_1.useEffect(() => {
const listener = state => {
const result = selector(state);
if (equalityFn
? !equalityFn(resultRef.current, result)
: resultRef.current !== result) {
forceUpdate({});
}
};
store.subscribe(listener);
return () => {
store.unsubscribe(listener);
};
}, []);
return resultRef.current;
};
function connect(mapStateToProps, actions) {
if (typeof mapStateToProps !== "function") {
mapStateToProps = select(mapStateToProps || []);
}
return (Child) => {
function Wrapper(props, context) {
react_1.Component.call(this, props, context);
const store = context;
let state = mapStateToProps(store ? store.getState() : {}, props);
const boundActions = actions ? mapActions(actions, store) : { store };
const update = () => {
const mapped = mapStateToProps(store ? store.getState() : {}, props);
for (const i in mapped) {
if (mapped[i] !== state[i]) {
state = mapped;
return this.forceUpdate();
}
}
for (const i in state) {
if (!(i in mapped)) {
state = mapped;
return this.forceUpdate();
}
}
};
this.UNSAFE_componentWillReceiveProps = (p) => {
props = p;
update();
};
this.componentDidMount = () => {
store.subscribe(update);
};
this.componentWillUnmount = () => {
store.unsubscribe(update);
};
this.render = () => react_1.createElement(Child, Object.assign(Object.assign(Object.assign({}, boundActions), this.props), state));
}
Wrapper.contextType = UnistoreContext;
return ((Wrapper.prototype = Object.create(react_1.Component.prototype)).constructor = Wrapper);
};
}
exports.connect = connect;
//# sourceMappingURL=index.js.map