|
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 |