使用类组件时如何根据屏幕大小断点更改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 时如何根据屏幕宽度更改项目大小