JSFiddle - React, Tailwind, and code Playground
HTML
<script src="http://fb.me/react-with-addons-0.8.0.js"></script>
<script src="http://fb.me/JSXTransformer-0.8.0.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.5.2/underscore.js"></script>
<script src="http://fb.me/react-js-fiddle-integration.js"></script>
CSS
body{overflow:scroll}.App{padding:10px;display:table}.App>div{padding:10px;display:table-cell;width:50%}.App>.pre{display:table-cell}
JavaScript 1.7
/** @jsx React.DOM */
var TopStateMixin = {
onChange: function (path, /* more paths,*/ value) {
path = _.flatten(_.initial(arguments));
value = _.last(arguments);
var nextState = deepClone(this.state);
var scoped = getRefAtPath(nextState, _.initial(path));
scoped[_.last(path)] = value;
this.setState(nextState);
function getRefAtPath (tree, paths) { return _.reduce(paths, deref, tree); }
function deref (obj, key) { return obj[key]; }
function deepClone(obj) { return JSON.parse(JSON.stringify(obj)); }
}
};
var App = React.createClass({
mixins: [TopStateMixin],
getInitialState: function () {
return {
foo: {
timer: 0,
bar: {
timer: 0,
baz: {
timer: 2
}
}
}
};
},
render: function () {
var sum = this.state.foo.timer + this.state.foo.bar.timer + this.state.foo.bar.baz.timer;
return (
<div className="App">
<div>
<Foo
value={this.state.foo}
onChange={_.partial(this.onChange, 'foo')} />
<p>Sum of timers: {sum}</p>
</div>
<pre>{JSON.stringify(this.state, undefined, 2)}</pre>
</div>
);
}
});
var Timer = React.createClass({
tick: function() { this.props.onChange(this.props.value + 1); },
componentDidMount: function() { this.interval = setInterval(this.tick, 1000); },
componentWillUnmount: function() { clearInterval(this.interval); },
render: function() { return (<div>{this.props.value}</div>); }
});
var Foo = React.createClass({
render: function () {
return (
<div className="Foo">
<Timer
value={this.props.value.timer}
...