Skip to content

Instantly share code, notes, and snippets.

@malerba118
Created November 21, 2018 04:09
Show Gist options
  • Select an option

  • Save malerba118/ce2eccea26a307ac852bf0f47dd696be to your computer and use it in GitHub Desktop.

Select an option

Save malerba118/ce2eccea26a307ac852bf0f47dd696be to your computer and use it in GitHub Desktop.
import React from "react"
import PropTypes from 'prop-types'
import Button from '@material-ui/core/Button'
class PromiseButtonBase extends React.Component {
state = {
promiseState: 'before'
}
componentWillUnmount() {
delete this.currentPromise
}
onClick = (e) => {
if (this.state.promiseState === 'pending' && this.props.disableOnPending) {
return
}
if (this.state.promiseState === 'fulfilled' && this.props.disableOnFulfilled) {
return
}
if (this.state.promiseState === 'rejected' && this.props.disableOnRejected) {
return
}
let promise = this.props.onClick(e)
this.currentPromise = promise
if (!promise || !(typeof promise.then === 'function')) {
return //not a promise
}
this.setState({
promiseState: 'pending'
})
promise
.then(() => {
if (promise !== this.currentPromise) {
return //promise has changed
}
this.setState({
promiseState: 'fulfilled'
})
})
.catch(() => {
if (promise !== this.currentPromise) {
return //promise has changed
}
this.setState({
promiseState: 'rejected'
})
})
}
render() {
const {
renderOnPending,
renderOnFulfilled,
renderOnRejected,
disableOnPending,
disableOnFulfilled,
disableOnRejected,
...other
} = this.props
return (
<Button {...other} onClick={this.onClick}>
{this.state.promiseState === 'before' && this.props.children}
{this.state.promiseState === 'pending' && this.props.renderOnPending()}
{this.state.promiseState === 'fulfilled' && this.props.renderOnFulfilled()}
{this.state.promiseState === 'rejected' && this.props.renderOnRejected()}
</Button>
)
}
}
PromiseButtonBase.propTypes = {
onClick: PropTypes.func,
renderOnPending: PropTypes.func,
renderOnFulfilled: PropTypes.func,
renderOnRejected: PropTypes.func,
disableOnPending: PropTypes.bool,
disableOnFulfilled: PropTypes.bool,
disableOnRejected: PropTypes.bool
}
PromiseButtonBase.defaultProps = {
onClick: () => {},
renderOnPending: () => {},
renderOnFulfilled: () => {},
renderOnRejected: () => {},
disableOnPending: true,
disableOnFulfilled: false,
disableOnRejected: false,
}
export default PromiseButtonBase
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment