首页 > 解决方案 > 使用类组件时如何根据屏幕大小断点更改 Material UIs Button 组件的 prop

问题描述

我正在使用 Material UI 的 Button 组件,并希望有条件地确定按钮的变体。也就是说,在中等及以上屏幕上,变体应为“轮廓”,当屏幕小于中等时,变体类型应为无。我正在使用一个类组件。我做了我的研究,看看其他人做了什么。我已经看到了使用 useMediaQuery 方法的方法,但这需要我将组件更改为功能组件。我不确定我是否知道这是否是一个好主意,因为该组件相当大,这意味着转换会有点混乱。我还尝试使用这样的三元运算符:

const variantType = theme.breakpoints.down("md") ? '' : 'outline';

<Button variant={variantType}>
       Food Pick
 </Button>

但这并没有起到作用。有没有其他方法可以做到这一点?

Update: Here is my code after trying to wrap the component but in a functional component but its giving an error:

在此处输入图像描述

import { withStyles, withTheme, useTheme } from '@material-ui/core';
import PropTypes from 'prop-types';
import Button from '@material-ui/core/Button';
import Typography from '@material-ui/core/Typography';
import Grid from '@material-ui/core/Grid';
import { PulseLoader } from 'react-spinners';
import Icon from '@material-ui/core/Icon';
import Chip from '@material-ui/core/Chip';
import useMediaQuery from '@material-ui/core/useMediaQuery';



const styles = theme => ({
  beta: {
    height: '17px',
    fontSize: '12px',
    marginLeft: '10px'
  },
  scrollContainer: {
    flex: 1,
    maxHeight: '400px',
    minHeight: '300px',
    overflowY: 'auto'
  },
  progressContainer: {
    height: '350px',
  },
  modalDescription: {
    color: theme.palette.text.secondary,
    marginTop: '20px',
  },
  button: {
    marginTop: '20px',
    marginLeft: '10px',
    marginRight: '10px',
  },
  smartSuggestContainer: {
    textAlign: 'right',
    paddingRight: '35px',
    [theme.breakpoints.down('xs')]: {
      display: 'flex',
      justifyContent: 'center',
      flexDirection: 'row',
      margin: '40px 0'
    },
  },
});

export default function MyComponentWrapper({ ...rest }) {
  const theme = useTheme();
  const mediumScreen = useMediaQuery(theme.breakpoints.down('md'));
  return <FoodDescriptions {...rest} mediumScreen={mediumScreen} />;
}

class FoodDescriptions extends Component {
  static PAGE_SIZE = 25;

  constructor(props) {
    super(props);

    this.state = {
      showFoodDescriptionsModal: false,
      dataLoaded: false,
      data: [],
      page: 0,
      sortBy: 'return',
      sortDir: 'desc',
    };
  }

  componentDidMount() {
    document.addEventListener('keydown', this.handleKeypress);
  }

  componentWillUnmount() {
    document.removeEventListener('keydown', this.handleKeypress);
  }

  fetchData = async (page, sortBy, sortDir) => {
    const { currentBotId } = this.props;
    const offset = page * FoodDescriptions.PAGE_SIZE;
    const data = await getFoodDescriptions(currentBotId, sortBy, sortDir, FoodDescriptions.PAGE_SIZE, offset);
    this.setState({
      dataLoaded: true,
      data,
    });
  };

  handleKeypress = (e) => {
    const { showSnartConfigsModal } = this.state;
    const { key } = e;
    if (key === 'Escape' && showSnartConfigsModal) {
      this.closeModal();
    }
  };

  applyConfig = (botId, params) => {
    const { updateConfig, botConfig, actions } = this.props;
    updateConfig({ name: botConfig.name, config: Object.assign(botConfig.config, params) });
    this.closeModal();
    actions.showNotification({ data: 'Configuration has been applied' });
  };

  openModal = () => {
    const { page, sortBy, sortDir } = this.state;
    this.fetchData(page, sortBy, sortDir);
    this.setState({
      showFoodDescriptionsModal: true,
    });
  };

  closeModal = () => {
    this.setState({
      showFoodDescriptionsModal: false,
    });
  };

  changePage = (page) => {
    const { sortBy, sortDir } = this.state;
    this.setState({
      page,
      dataLoaded: false
    }, () => this.fetchData(page, sortBy, sortDir));
  };

  changeSortBy = (sortBy) => {
    /* eslint-disable-next-line prefer-destructuring */
    let sortDir = this.state.sortDir;
    if (sortBy === this.state.sortBy) {
      sortDir = (this.state.sortDir === 'desc') ? 'asc' : 'desc';
    }
    this.setState({
      sortBy,
      sortDir,
      dataLoaded: false,
    }, () => this.fetchData(this.state.page, sortBy, sortDir));
  };

  renderEmptyState() {
    const { classes } = this.props;
    return (
      <Grid container alignItems="center" justify="center" className={classes.progressContainer}>
        <Typography className={classes.noCoinsText}>No configurations found</Typography>
      </Grid>
    );
  }

  renderLoader() {
    const { classes } = this.props;
    return (
      <Grid container alignItems="center" justify="center" className={classes.progressContainer}>
        <PulseLoader size={6} color="#52B0B0" loading />
      </Grid>
    );
  }

  renderTable() {
    const { data, page } = this.state;
    return (
      <StrategiesTable
        strategies={data}
        onClickCopy={this.applyConfig}
        page={page}
        changePage={this.changePage}
        sortBy={this.changeSortBy} />
    );
  }

  render() {
    const {
      classes, userFeatures, botConfig, theme
    } = this.props;
    const { showFoodDescriptionsModal, dataLoaded } = this.state;

    if (!botConfig) {
      return null;
    }

    return (
      <Fragment>
        <div className={classes.smartSuggestContainer}>
          <Button
            name="discoverConfigs"
            variant={theme.breakpoints.down(600) ? '' : 'outlined'}
            color="primary"
            size="small"
            disabled={!userFeatures['smart_suggest_backtests'.toUpperCase()] || botConfig.status.toLowerCase() === STATUSES.RUNNING}
            onClick={this.openModal}>
           
            Food Buy
          </Button>
          </div>
      </Fragment>
    );
  }
}



function mapStateToProps(state) {
  return {
    userFeatures: state.global.paywall.features,
  };
}

function mapDispatchToProps(dispatcher) {
  return {
    actions: {
      ...bindActionCreators({
        showNotification,
      }, dispatcher)
    }
  };
}

connect(mapStateToProps, mapDispatchToProps)(withTheme()(withStyles(styles)(FoodDescriptions)));

标签: javascriptcssreactjsmaterial-uimedia-queries

解决方案


为什么不使用 useMediaQuery 创建一个功能组件并返回响应式 Button ?


推荐阅读