Skip to content

Instantly share code, notes, and snippets.

@heyimalex
Last active July 14, 2017 05:46
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save heyimalex/5afb9d451fc681eae790 to your computer and use it in GitHub Desktop.
Save heyimalex/5afb9d451fc681eae790 to your computer and use it in GitHub Desktop.
Helper for dealing with promise-y state in React.js
const PENDING = 0;
const FULFILLED = 1;
const REJECTED = 2;
function PromiseState(component, stateKey, initial) {
this.component = component;
this.stateKey = stateKey;
var self = this;
this.boundSetPromise = function(nextPromise, val) {
self.setPromise(nextPromise, val);
}
this.setPromise(initial);
};
PromiseState.prototype.setPromise = function(nextPromise) {
this.setState(PENDING, nextPromise);
var self = this;
nextPromise
.then(function(value) {
if (nextPromise === self.promise) {
self.setState(FULFILLED, value);
}
}, function(reason) {
if (nextPromise === self.promise) {
self.setState(REJECTED, reason);
}
});
};
PromiseState.prototype.setState = function(nextState, val) {
switch(nextState) {
case PENDING:
this.promise = val;
this.pending = true;
this.fulfilled = false;
this.rejected = false;
this.settled = false;
break;
case FULFILLED:
this.value = val;
this.pending = false;
this.fulfilled = true;
this.rejected = false;
this.settled = true;
break;
case REJECTED:
this.reason = val;
this.pending = false;
this.fulfilled = false;
this.rejected = true;
this.settled = true;
break;
}
var nextState = {};
nextState[this.stateKey] = {
promise: this.promise,
value: this.value,
reason: this.reason,
pending: this.pending,
fulfilled: this.fulfilled,
rejected: this.rejected,
settled: this.settled,
set: this.boundSetPromise
};
// Use try in case the component has already been
// unmounted. Can't use isMounted as setState is often
// called from componentWillMount.
try { this.component.setState(nextState); }
catch (e) { return; }
};
var PromisePropMixin = function(propKey, stateKey) {
if (stateKey === undefined) {
stateKey = propKey;
}
return {
componentWillMount: function() {
new PromiseState(this, stateKey, this.props[propKey]);
},
componentWillReceiveProps: function(nextProps) {
if (this.props[propKey] !== nextProps[propKey]) {
this.state[stateKey].set(nextProps[propKey]);
}
}
};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment