Skip to content

Instantly share code, notes, and snippets.

@iddan
Created June 29, 2017 09:12
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 iddan/76e4cfd7fb4c8e65fc4594099b14f231 to your computer and use it in GitHub Desktop.
Save iddan/76e4cfd7fb4c8e65fc4594099b14f231 to your computer and use it in GitHub Desktop.
repx
import React from 'react';
import connect from './connect';
// model
class User {
name = null;
}
// view
const _App = ({ user }) => user.name === null
? <button onClick={ () => user.name = 'Iddan Aharonson' }>Login</button>
: <input type="text"
value={ user.name }
onChange={ e => user.name = e.target.value } />;
const App = connect({ user: new User() })(_App);
ReactDOM.render(<App />, document.queyrSelector('#root');
import React, { Component } from 'react';
import Model, { subscribe } from './model';
import 'proxy-polyfill';
/**
* @param {Object<Object>} models
* @returns {function}
*/
const connect = (models) =>
/**
* @param {function} WrappedComponent
* @returns {Class<Component>}
*/
(WrappedComponent) => class extends Component {
static displayName = `Connect(${ WrappedComponent.displayName || WrappedComponent.name })`;
models = Model(models);
unsubscribe = this.models[subscribe](() => this.forceUpdate());
componentWillUnmount() {
this.unsubscribe();
}
render() {
return <WrappedComponent { ...this.props } { ...this.models } />;
}
};
export const subscribe = '__subscribe__';
/**
* @typedef {Proxy} Model
* @property {function} subscribe
*/
/**
* @param {Object} target
* @param {Array<function>} [handlers]
* @returns {Model}
*/
const Model = (target, handlers = []) => {
target[subscribe] = (handler) => {
handlers.push(handler);
return () => {
handlers.splice(handlers.findIndex(a => a === handler), 1);
};
};
Object.seal(target);
const proxy = new Proxy(target, {
get(target, property) {
const value = target[property];
if (typeof value !== 'object' || value === null) {
return value;
}
return Model(value, handlers);
},
set(target, property, value) {
target[property] = value;
for (const handler of handlers) {
handler(property, value);
}
return true;
},
});
return proxy;
};
export default Model;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment