Skip to content

Instantly share code, notes, and snippets.

@BinaryMuse
Created November 3, 2014 16:20
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save BinaryMuse/3b0a4ba166ac81840cab to your computer and use it in GitHub Desktop.
Save BinaryMuse/3b0a4ba166ac81840cab to your computer and use it in GitHub Desktop.
Async fetches initiated by the store when necessary
// Component
var AnswerDisplay = React.createClass({
mixins: [FluxMixin, StoreWatchMixin("answer")],
getStateFromFlux() {
var flux = this.getFlux(),
answerStore = flux.store("answer");
return {
// getAnswer() is synchronous, but might trigger an async request in the store—see below
answer: answerStore.getAnswer(this.props.params.answerId) // from react-router
};
},
render() {
if (this.state.answer === AnswerStore.LOADING_TOKEN) {
return <div>Loading...</div>;
} else {
return ... // the real component w/ the data shown
// Answer Store
var LOADING_TOKEN = {};
var AnswerStore = Fluxxor.createStore({
initialize({db}) {
this.db = db;
this.state = {
answers: {}
};
this.bindActions("ANSWER_FETCHED", this.handleAnswerFetched);
},
getAnswer(answerId) {
// If we don't have the answer cached, do an async load
// For now, set the value to LOADING_TOKEN so the component
// can show a loading indicator.
//
// If we DO have something cached, just return it.
// Important to note that this function is fully synchronous.
if (!this.state.answers[answerId]) {
this.state.answers[answerId] = LOADING_TOKEN;
this._loadAnswer(answerId);
return LOADING_TOKEN;
} else {
return this.state.answers[answerId];
}
},
_loadAnswer(answerId) {
// This function is async, but we don't update ourselves when we get the data;
// instead, we dispatch an action so we update ourselves.
this.db.get("answers:" + answerId).then((data) => {
// Doing a custom dispatch here; might be pseudocode.
// Fluxxor doesn't have a nice way to do it yet,
// but you can just call an action to do so if you want.
this.flux.dispatcher.dispatch({type: "ANSWER_FETCHED", payload: {id: answerId, data: data}});
});
},
handleAnswerFetched(payload) {
this.state.answers[payload.id] = payload.data;
// when we emit a change event, AnswerDisplay will re-render,
// and this time when it calls actionStore.getAnswer,
// there will be a value.
this.emit("change");
}
});
AnswerStore.LOADING_TOKEN = LOADING_TOKEN;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment