使用类组件时如何根据屏幕大小断点更改Material UI Button组件的prop

Posted

技术标签:

【中文标题】使用类组件时如何根据屏幕大小断点更改Material UI Button组件的prop【英文标题】:How to change prop of Material UIs Button component based on screen size breakpoint when using a class component 【发布时间】:2021-10-02 17:14:57 【问题描述】:

我正在使用 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)));

【问题讨论】:

您不必转换整个组件。只需创建一个新组件来包装处理此方面的按钮并在您的类组件中使用该组件。 嗨 Ryan,我已经尝试过了,但遇到了错误。您能否查看我的代码,看看它是否与您的意思相同?谢谢! @RyanCogswell 请在code sandbox 中分享相关代码的简化版本,重现您的问题。 【参考方案1】:

您为什么不直接使用 useMediaQuery 创建一个功能组件并返回响应式按钮?

【讨论】:

您好,感谢您的意见。我已尝试过您的建议,但出现错误。我还用我的代码更新了帖子

以上是关于使用类组件时如何根据屏幕大小断点更改Material UI Button组件的prop的主要内容,如果未能解决你的问题,请参考以下文章

使用样式组件在反应中根据屏幕分辨率的变化更改字体大小

使用 UICollectionViewCompositionalLayout 时如何根据屏幕宽度更改项目大小

React / Gatsby - 根据屏幕大小渲染不同的组件

根据屏幕大小/媒体查询更改 Bootstrap 列类属性

是否可以在样式组件中使用样式系统的断点?

根据屏幕大小切换 CSS 类