Skip to content

Instantly share code, notes, and snippets.

@confiks
Last active August 29, 2015 14:13
Show Gist options
  • Save confiks/745d27f7308db1935eb9 to your computer and use it in GitHub Desktop.
Save confiks/745d27f7308db1935eb9 to your computer and use it in GitHub Desktop.
A tightly coupled example of how to use Immutable.js cursors together with React and a Reflux-like store
// This is a tightly coupled example of how to use Immutable.js cursors
// together with React and a Reflux-like store
// The store should be Reflux-like: the store is emitted to components using this.trigger()
// The store should emit this.stateCursor when components ask for its current state
var TurtlesStore = SomeStoreFactory.createStore({
init: () => {
this.state = Immutable.fromJS({turtles: []});
this.stateCursor = this._cursorRec(this.state);
},
// Note: I have no idea if these recursive calls leak memory
_cursorRec: (state) => {
return ImmutableContribCursor.from(state, (updatedState, _componentState, keyPath) => {
// We only merge the updatedState into this.state at the point of the change
var mergedState = this.state.setIn(keyPath, updatedState.getIn(keyPath));
this.state = mergedState;
this.stateCursor = this._getStateCursor(this.state);
this.trigger(this.stateCursor)
});
},
// Actions:
// Beside the 'turtles' key, we could emit more data, such as selectedTurtles
onReceiveTurtles: (turtles) => {
this.stateCursor.set('turtles', turtles);
},
onSendTurtles: () => {
Pigeon.send(this.state.get('turtles'));
}
});
var TurtlesComponent = React.createClass({
componentWillMount: function() {
this.setState({turtlesCursor: TurtleStore.getCurrentState()});
TurtlesStore.listen( (newTurtlesCursor) =>
this.setState({turtlesCursor: newTurtlesCursor})
);
},
onAddButtonClick: function(e) {
this.state.turtlesCursor.updateIn('turtles', (turtles) =>
turtles.push(e.target.turtle)
);
// Warning: 'Synchronous' cursor updates to the same keyPath will clobber an earlier update
// Synchronous here means: without a React setState in between that sets the updated cursor
// Note that React's setState behaves exactly the same
},
renderTurtleCount: function() {
return <div>{this.state.turtlesCursor.deref().size}</div>;
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment