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

React实现底部弹出Drawer时触发Too many re-renders错误求助

解决React组件无限重渲染问题

你的代码出现Too many re-renders. React limits the number of renders to prevent an infinite loop.错误,核心原因是直接在事件属性中调用状态更新函数,导致组件每次渲染时都会触发状态变更,进而引发无限渲染循环。

具体问题点:

  • Button的onClick={setActionBarOpen(true)}:组件渲染时会立即执行setActionBarOpen(true),更新状态后触发重新渲染,反复循环。
  • Box的onClick={setActionBarOpen(false)}和onKeyDown={setActionBarOpen(false)}:同样在组件渲染时直接执行状态更新函数,加重循环问题。

修正后的代码:

import * as React from "react";
import Box from "@mui/material/Box";
import Drawer from "@mui/material/Drawer";
import Button from "@mui/material/Button";
import List from "@mui/material/List";
import ListItem from "@mui/material/ListItem";
import ListItemButton from "@mui/material/ListItemButton";
import ListItemIcon from "@mui/material/ListItemIcon";
import ListItemText from "@mui/material/ListItemText";
import InboxIcon from "@mui/icons-material/MoveToInbox";
import MailIcon from "@mui/icons-material/Mail";

export default function TemporaryDrawer() {
  const [actionBarOpen, setActionBarOpen] = React.useState(false);

  const closeActionBar = () => {
    setActionBarOpen(false);
  };

  const list = (
    <Box
      role="presentation"
      onClick={() => setActionBarOpen(false)}
      onKeyDown={() => setActionBarOpen(false)}
    >
      <List>
        {["Inbox", "Starred", "Send email", "Drafts"].map((text, index) => (
          <ListItem key={text} disablePadding>
            <ListItemButton>
              <ListItemIcon>
                {index % 2 === 0 ? <InboxIcon /> : <MailIcon />}
              </ListItemIcon>
              <ListItemText primary={text} />
            </ListItemButton>
          </ListItem>
        ))}
      </List>
    </Box>
  );

  return (
    <div>
      <React.Fragment key="bottom">
        <Button onClick={() => setActionBarOpen(true)}>Click me</Button>
        <Drawer anchor="bottom" open={actionBarOpen} onClose={closeActionBar}>
          {list}
        </Drawer>
      </React.Fragment>
    </div>
  );
}

修改说明:

  • 将onClick={setActionBarOpen(true)}改为onClick={() => setActionBarOpen(true)}:传递一个函数引用,只有当按钮被点击时才会执行状态更新。
  • 同理,Box的onClick和onKeyDown也改为函数形式() => setActionBarOpen(false),确保只有在事件触发时才执行状态变更。

这样修改后,组件只会在用户交互(点击按钮、点击/按下键盘关闭抽屉)时更新状态,避免了无限渲染循环,Drawer也能正常从底部弹出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 01:40:10