Skip to content

Instantly share code, notes, and snippets.

@JAStanton
Created May 26, 2015 02:18
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 JAStanton/ec475503f9b7e5347017 to your computer and use it in GitHub Desktop.
Save JAStanton/ec475503f9b7e5347017 to your computer and use it in GitHub Desktop.
import React from 'react/addons';
import { Input } from 'react-bootstrap';
class StateProxy {
constructor(rootComponent, pathPrefix) {
this._rootComponent = rootComponent;
this._pathPrefix = pathPrefix;
}
get(path) {
return _.get(this._rootComponent.state, this._pathPrefix.concat(path));
}
set(path, value) {
let stateClones = _.cloneDeep(this._rootComponent.state);
_.set(stateClones, this._pathPrefix.concat(path), value);
this._rootComponent.setState(stateClones);
}
child(pathPrefix) {
return new this.constructor(this._rootComponent, this._pathPrefix.concat(pathPrefix));
}
}
let ReactLinkTroix = {
componentWillMount() {
this._stateProxy = this.props.stateProxy || new StateProxy(this, []);
this._stateProxy._thisComponent = this;
},
linkState(...path) {
let callback;
if (_.isFunction(path[path.length - 1])) {
callback = path.pop();
}
let stateProxy = this._stateProxy;
let that = this;
return {
value: this._stateProxy.get(path),
requestChange(newValue) {
stateProxy.set(path, newValue);
if (_.isFunction(callback)) callback(path, newValue);
}
}
},
linkStateProxy(...pathPrefix) {
return this._stateProxy.child(pathPrefix, this);
},
}
let ChildB = React.createClass({
mixins: [ReactLinkTroix],
render() {
return (
<div>
<input valueLink={this.linkState('lat')} placeholder="form.address.coord.lat" />
<input valueLink={this.linkState('long')} placeholder="form.address.coord.long" />
</div>
);
},
});
let ChildA = React.createClass({
mixins: [ReactLinkTroix],
onValueChanged(path, value) {
console.log('My', path.join('.'), 'just changed to', value, this);
},
render() {
return (
<div>
<input valueLink={this.linkState('full', this.onValueChanged)} placeholder="form.address.full" />
<ChildB stateProxy={this.linkStateProxy('coord')} />
</div>
);
}
});
export default React.createClass({
mixins: [ReactLinkTroix],
getInitialState() {
return {
form: {
name: 'initial name',
address: {
full: 'initial full',
coord: {
lat: 123,
long: 456
},
},
},
};
},
handleHandleForFormName() {
console.log("handle form name chanded", arguments);
},
componentWillUpdate(nextProps, nextState) {
console.log("top level did change", nextState);
},
render() {
return (
<div>
<div>Hello</div>
<input valueLink={this.linkState('form', 'name')} placeholder="form.name" />
<ChildA stateProxy={this.linkStateProxy('form', 'address')} />
</div>
);
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment