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

React中Material UI Drawer刷新后如何实现滚动到底部?

解决Material UI Drawer触发API请求后滚动位置重置的问题

问题背景

在高级搜索页面使用Material UI Drawer,内置大量复选框和单选按钮,点击时触发API GET请求实时获取结果,但每次请求都会导致Drawer滚动回顶部。由于单选按钮位于Drawer底部,希望点击时强制Drawer滚动到底部,模拟保留原滚动位置。

可行解决方案

方法1:利用useRef+useEffect监听状态变化实现滚动

通过useRef获取Drawer的Paper容器,监听单选按钮的选中状态变化,在组件重渲染完成后执行滚动操作:

import { useRef, useEffect, useState } from 'react';
import Drawer from '@mui/material/Drawer';
import Radio from '@mui/material/Radio';
import RadioGroup from '@mui/material/RadioGroup';
import FormControlLabel from '@mui/material/FormControlLabel';

export default function AdvancedSearchDrawer() {
  const drawerPaperRef = useRef(null);
  const [selectedSortMetric, setSelectedSortMetric] = useState('');

  // 监听选中状态变化,执行滚动
  useEffect(() => {
    if (drawerPaperRef.current) {
      drawerPaperRef.current.scrollTop = drawerPaperRef.current.scrollHeight;
    }
  }, [selectedSortMetric]);

  const handleMetricChange = (e) => {
    const value = e.target.value;
    setSelectedSortMetric(value);
    // 触发API请求
    fetch(`/api/search?sort=${value}`)
      .then(res => res.json())
      .then(data => {
        // 处理返回结果
      });
  };

  return (
    <Drawer
      anchor="right"
      open={true}
      PaperProps={{
        ref: drawerPaperRef,
        style: { width: 320, overflowY: 'auto' }
      }}
    >
      {/* 其他搜索选项(复选框等) */}
      <RadioGroup value={selectedSortMetric} onChange={handleMetricChange}>
        <FormControlLabel value="metric1" control={<Radio />} label="Sorting Metric 1" />
        <FormControlLabel value="metric2" control={<Radio />} label="Sorting Metric 2" />
        <FormControlLabel value="metric3" control={<Radio />} label="Sorting Metric 3" />
      </RadioGroup>
    </Drawer>
  );
}

方法2:用requestAnimationFrame延迟滚动操作

如果直接在onChange中执行滚动无效,是因为组件重渲染尚未完成,DOM状态未更新。使用requestAnimationFrame将滚动操作推迟到下一次浏览器渲染周期:

// 给Drawer的Paper添加id
<Drawer
  PaperProps={{
    id: 'drawer-paper',
    style: { width: 320, overflowY: 'auto' }
  }}
>
  {/* 内容 */}
</Drawer>

// 单选按钮的onChange处理函数
const handleMetricChange = (e) => {
  const value = e.target.value;
  setSelectedSortMetric(value);
  fetch(`/api/search?sort=${value}`)
    .then(res => res.json())
    .then(data => { /* 处理结果 */ });

  // 延迟执行滚动
  requestAnimationFrame(() => {
    const drawerPaper = document.getElementById('drawer-paper');
    if (drawerPaper) {
      drawerPaper.scrollTop = drawerPaper.scrollHeight;
    }
  });
};

为什么之前的方法失效?

  • 第一种方法报错Cannot read properties of undefined (reading 'getScrollElement'):Material UI的Drawer并未公开getScrollElement方法,调用内部未暴露的API会导致报错,不要依赖这类非公开接口。
  • 第二种方法直接设置滚动无效:滚动操作执行时机过早,组件重渲染还未完成,DOM元素的滚动状态尚未更新,导致滚动指令未生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 16:02:38