Created
November 3, 2014 16:20
-
-
Save BinaryMuse/3b0a4ba166ac81840cab to your computer and use it in GitHub Desktop.
Async fetches initiated by the store when necessary
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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