Answer a question

I am using react with MUI framework and I was wondering how can I create an loading button using this framework?

I am looking for something similar to this.

Answers

To the best of my knowledge, there is no single component that accomplishes this out of the box in material-ui. However, you can implement your own easily using CircularProgress.

Assuming you are using material-ui v1, here's a rough example. First, I create a LoadingButton that accepts a loading prop - if that prop is true, I display a CircularProgress indicator. It also accepts a done prop - if that's true, the button clears the progress indicator and becomes a checkmark to show success.

import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from 'material-ui/styles';
import Button from 'material-ui/Button';
import { CircularProgress } from 'material-ui/Progress';
import Check from 'material-ui-icons/Check';

const styles = theme => ({
  button: {
    margin: theme.spacing.unit,
  },
});

const LoadingButton = (props) => {
  const { classes, loading, done, ...other } = props;

  if (done) {
    return (
      <Button className={classes.button} {...other} disabled>
        <Check />
      </Button>
    );
  }
  else if (loading) {
    return (
      <Button className={classes.button} {...other}>
        <CircularProgress />
      </Button>
    );
  } else {
    return (
      <Button className={classes.button} {...other} />
    );
  }
}

LoadingButton.defaultProps = {
  loading: false,
  done: false,
  };

LoadingButton.propTypes = {
  classes: PropTypes.object.isRequired,
  loading: PropTypes.bool,
  done: PropTypes.bool,
};

export default withStyles(styles)(LoadingButton);

You can use the LoadingButton as shown in the following example, which uses state to set the appropriate prop on the button.

import React from 'react';
import LoadingButton from './LoadingButton';

class ControlledButton extends React.Component {
  constructor(props) {
    super(props);

    this.state = { loading: false, finished: false };
  }

  render() {
    const { loading, finished } = this.state;

    const setLoading = !finished && loading;

    return (
      <div>
        <LoadingButton
          loading={setLoading}
          done={finished}
          onClick={() => {
            // Clicked, so show the progress dialog
            this.setState({ loading: true });

            // In a 1.5 seconds, end the progress to show that it's done
            setTimeout(() => { this.setState({ finished: true })}, 1500);
          }}
        >
          Click Me
        </LoadingButton>
      </div>
    );
  }
}

export default ControlledButton;

You can of course tweak the styling and functionality to meet your exact needs.

Logo

React社区为您提供最前沿的新闻资讯和知识内容

更多推荐