You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何监听Material-UI中Hidden组件的显示与隐藏状态?

监听Hidden组件状态变化并动态调整News组件内边距

我来帮你搞定这个需求!其实你不需要直接去监听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高阶组件来监听当前屏幕的断点:

  1. 先导入需要的模块:
import { withWidth, Hidden } from '@material-ui/core';
  1. 修改你的组件,通过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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:02:12