如何监听Material-UI中Hidden组件的显示与隐藏状态?
我来帮你搞定这个需求!其实你不需要直接去监听Hidden组件的显示/隐藏状态,因为Material-UI的Hidden组件本身是基于屏幕断点来控制元素显示的,我们可以通过监听屏幕断点变化或者CSS媒体查询这两种更优雅的方式来实现你的需求,下面给你详细讲两种方案:
方案一:用CSS媒体查询(最推荐,样式与逻辑分离)
这种方式不需要写JS逻辑,直接通过Material-UI的主题断点来定义不同屏幕尺寸下的样式,代码更简洁易维护。
首先修改你的样式定义,给News容器添加断点适配的内边距:
import { makeStyles } from '@material-ui/core/styles'; const useStyles = makeStyles((theme) => ({ root: { // 你的原有样式 }, demo: { // 你的原有样式 }, paper: { // 你的原有样式 }, // 新增News容器的样式 newsContainer: { paddingLeft: 300, // xsUp时的内边距,对应Categories的宽度+间距 zIndex: 0, // xs及以下屏幕时,内边距设为0 [theme.breakpoints.down('xs')]: { paddingLeft: 0, }, }, }));
然后在组件中把原来的style替换成这个类:
// 替换之前的Grid组件 <Grid container item lg={12} md={12} spacing={16} className={classes.newsContainer}> {news} </Grid>
这样就完成了!Material-UI会自动帮你生成对应的媒体查询CSS,在屏幕尺寸降到xs及以下时,自动把News的paddingLeft改成0,完全符合你的需求。
方案二:用withWidth高阶组件(类组件适用,适合需要JS逻辑处理的场景)
如果你的需求后续有更复杂的JS逻辑要结合断点变化,那可以用Material-UI提供的withWidth高阶组件来监听当前屏幕的断点:
- 先导入需要的模块:
import { withWidth, Hidden } from '@material-ui/core';
- 修改你的组件,通过props获取当前屏幕断点,动态计算paddingLeft:
class YourComponent extends React.Component { render() { const { classes, width } = this.props; // 判断当前是否是xs及以下屏幕 const isXsScreen = width === 'xs'; // 动态设置内边距:xs屏幕设为0,其他情况用300 const newsPadding = isXsScreen ? 0 : 300; let news = this.props.news.map((item, index) => { return ( <Zoom in={true} timeout={500}> <Grid item lg={3} xs={12} sm={12} md={6} lg={4} key={item.uid} spacing={16}> <Paper elevation={0} className={classes.paper}> <RecipeReviewCard info={item} /> </Paper> </Grid> </Zoom> ); }); return ( <div className={classes.root}> <Grid container className={classes.root}> <Grid item xs={12}> <Grid container spacing={16} className={classes.demo} alignItems={this.state.alignItems} direction={this.state.direction} justify={this.state.justify}> <Hidden xsDown> <Grid item lg={2} md={4} style={{ width: 270, maxWidth: 280, minWidth: 270, position: 'absolute', height: '100%', zIndex: 1 }}> <Categories /> </Grid> </Hidden> <Grid container item lg={12} md={12} spacing={16} style={{ paddingLeft: newsPadding, zIndex: 0 }}> {news} </Grid> </Grid> </Grid> </Grid> </div> ); } } // 用withWidth包装组件,让组件能获取当前屏幕断点 export default withWidth({ breakpoints: ['xs', 'sm', 'md', 'lg', 'xl'], width: 'window' })(YourComponent);
补充说明
为什么不直接监听Hidden组件?因为Hidden组件本身并没有暴露状态变化的回调,它本质上是通过CSS媒体查询或JS控制元素的display属性来实现隐藏/显示的,所以直接针对断点做处理是更合理的方式。
如果你的Categories组件宽度是动态变化的(不是固定270),那可以结合ResizeObserver来获取它的实际宽度,不过如果是固定宽度的话,方案一的CSS方式绝对是最优解~
内容的提问来源于stack exchange,提问作者Tazo leladze
相关产品推荐
相关产品推荐

