You need to enable JavaScript to run this app. React中如何实现列表项高度从固定300px动态设置为auto?
优惠活动
大模型
产品
解决方案
定价
更多

React中如何实现列表项高度从固定300px动态设置为auto?

问题原因

  • 你更新expandedArray状态时直接修改了原数组引用,React状态更新依赖引用变化判断是否重渲染,原数组引用没有改变的情况下,组件不会触发重新渲染,高度自然不会更新。
  • 展开按钮放在了设置overflow: hidden的内部容器中,当内容高度超过300px时,按钮会被截断隐藏,无法触发点击事件。

修正方案

  1. 修改状态更新逻辑,每次更新创建新的数组,保证引用变化触发重渲染
  2. 将展开按钮移动到固定高度的容器外部,保证按钮始终可见
  3. 可选优化:可以先判断内容实际高度是否小于300px,若不足则直接隐藏展开按钮,避免无意义的交互

修正后代码

const IndexPage: React.FC<IndexPageProps> = ({}) => {
  const classes = useStyles();
  const [{ data, fetching }] = useGetGroupsQuery();

  const [expandedArray, setExpandedArray] = useState<number[]>([]);

  const handleExpandClick = (id: number) => {
    // 直接创建新数组,不修改原state引用
    setExpandedArray(prev => [...prev, id]);
  };

  const getHeight = (id: number) => {
    if (!expandedArray.includes(id)) {
      return { height: 300 };
    } else {
      return { height: "auto" };
    }
  };

  return (
    <Layout variant="regular">
      {!fetching && data ? (
        <Grid container direction="column" spacing={2}>
          {data.groups.map((group) => {
            return (
              <Grid xs={12} item key={group.id}>
                <Paper>
                  <Box className={classes.paddedBox}>
                    {/* 高度控制的容器只包裹内容,不放展开按钮 */}
                    <Box overflow="hidden" style={getHeight(group.id)}>
                      <NextLink
                        href="/class/cliques/[group.slug]"
                        as={`/class/cliques/${group.slug}`}
                      >
                        <Typography variant="h4" className={classes.groupName}>
                          <Link color="inherit">{group.name}</Link>
                        </Typography>
                      </NextLink>
                      <Typography variant="h5">Description</Typography>
                      <Typography className={classes.preline}>
                        {group.description}
                      </Typography>
                      <Typography variant="h5">Requirements</Typography>
                      <Typography className={classes.preline}>
                        {group.requirements}
                      </Typography>
                    </Box>
                    {/* 展开按钮移到外层 */}
                    <Box
                      className={classes.expandMoreBlock}
                      onClick={() => handleExpandClick(group.id)}
                    >
                      <IconButton className={classes.expandMore}>
                        <ExpandMoreRounded />
                      </IconButton>
                    </Box>
                  </Box>
                </Paper>
              </Grid>
            );
          })}
        </Grid>
      ) : null}
    </Layout>
  );
};

额外说明

如果需要加展开收起的过渡动画,不要直接用height: auto,可以换成动态设置max-height属性,从300px改为一个足够容纳内容的固定值(比如2000px),就可以实现平滑的过渡效果。

内容的提问来源于stack exchange,提问作者JunKang Ng

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 20:06:07