Skip to content

Instantly share code, notes, and snippets.

@JamiesWhiteShirt
Created August 2, 2019 14:45
Show Gist options
  • Save JamiesWhiteShirt/bbf74a11ddb153a6eb709b67974c8721 to your computer and use it in GitHub Desktop.
Save JamiesWhiteShirt/bbf74a11ddb153a6eb709b67974c8721 to your computer and use it in GitHub Desktop.
import React from 'react';
import PropTypes from 'prop-types';
import KsPropTypes from 'ks/components/KsPropTypes';
const statusTypes = {
none: 'none',
pending: 'pending',
rejected: 'rejected',
resolved: 'resolved',
};
class Async extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
status: statusTypes.none,
value: null,
};
}
componentWillMount() {
this.handlePromise(this.props.promise);
}
componentWillReceiveProps(nP) {
if (nP.promise !== this.props.promise) {
this.forceUpdate();
this.handlePromise(nP.promise);
}
}
handlePromise(prom) {
if (prom) {
this.setState({
status: statusTypes.pending,
value: null,
});
prom.then((res) => {
if (this.props.promise === prom) {
this.setState({
status: statusTypes.resolved,
value: res,
});
}
}, (err) => {
if (this.props.promise === prom) {
this.setState({
status: statusTypes.rejected,
value: err,
});
}
});
} else {
this.setState({
status: statusTypes.none,
value: null,
});
}
}
render() {
switch (this.state.status) {
case statusTypes.none:
return this.props.none(this.handlePromise.bind(this));
case statusTypes.pending:
return this.props.pending();
case statusTypes.resolved:
return this.props.resolved(this.state.value);
case statusTypes.rejected:
return this.props.rejected(this.state.value);
default:
throw new Error('Invalid Async state');
}
}
}
Async.propTypes = {
promise: KsPropTypes.promiseLike, // promise itself
none: PropTypes.func, // renders its return value before promise is handled
pending: PropTypes.func.isRequired, // renders its return value when promise is pending
resolved: PropTypes.func.isRequired, // renders its return value when promise is resolved
rejected: PropTypes.func.isRequired, // renders its return value when promise is rejected
};
Async.defaultProps = {
promise: null,
none: null,
};
export default Async;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment