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

Material UI 搜索输入触发侧边栏打开功能失效如何解决

问题根因

  • toggleDrawer为柯里化函数,设计用于返回事件监听回调,直接调用toggleDrawer("right", true)只会生成一个未执行的函数,不会触发状态更新
  • 对propssearchInput的变更监听逻辑放在组件渲染顶层,无法在props更新时触发对应逻辑,且渲染过程中直接修改状态会导致异常重渲染
  • 原有获取消息数据的useEffect逻辑错误,将数据请求放在了组件卸载的清理函数中,无法正常拿到数据

修复方案

  1. 新增useEffect监听searchInput的变化,输入内容非空时直接修改抽屉打开状态
  2. 修正数据获取的useEffect逻辑,将数据请求放到组件挂载阶段执行
  3. 移除组件顶层的无效if判断
import { Fragment, useEffect, useState } 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 Divider from "@mui/material/Divider";
import ListItem from "@mui/material/ListItem";
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";
import { collection, getDocs } from "@firebase/firestore";
import db from "../../firebase";

export default function SearchDrawer({ searchInput }) {
  const [messages, setMessages] = useState([]);
  const [state, setState] = useState({
    right: false,
  });

  // 修正后的数据获取逻辑,挂载时执行请求
  useEffect(() => {
    const getMessages = async () => {
      const channels = await getDocs(collection(db, "channels"));
      channels.forEach(async (channel) => {
        const msgs = await getDocs(
          collection(db, "channels", channel.id, "messages")
        );
        msgs.forEach((msg) => {
          setMessages((prev) => [...prev, msg.data()]);
        });
      });
    };
    getMessages()
    // 卸载时清空消息
    return () => setMessages([])
  }, []);

  // 新增监听searchInput的副作用,输入时打开侧边栏
  useEffect(() => {
    if (!!searchInput) {
      setState(prev => ({...prev, right: true}))
    }
  }, [searchInput])

  const toggleDrawer = (anchor, open) => (event) => {
    if (
      event.type === "keydown" &&
      (event.key === "Tab" || event.key === "Shift")
    ) {
      return;
    }
    setState({ ...state, [anchor]: open });
  };

  const list = (anchor) => (
    <Box
      sx={{ width: anchor === "top" || anchor === "bottom" ? "auto" : "45vw" }}
      role="presentation"
      onClick={toggleDrawer(anchor, false)}
      onKeyDown={toggleDrawer(anchor, false)}
    >
      <List>
        {["Inbox", "Starred", "Send email", "Drafts"].map((text, index) => (
          <ListItem button key={text}>
            <ListItemIcon>
              {index % 2 === 0 ? <InboxIcon /> : <MailIcon />}
            </ListItemIcon>
            <ListItemText primary={text} />
          </ListItem>
        ))}
      </List>
      <Divider />
      <List>
        {["All mail", "Trash", "Spam"].map((text, index) => (
          <ListItem button key={text}>
            <ListItemIcon>
              {index % 2 === 0 ? <InboxIcon /> : <MailIcon />}
            </ListItemIcon>
            <ListItemText primary={text} />
          </ListItem>
        ))}
      </List>
    </Box>
  );

  return (
    <>
      <Fragment key={"right"}>
        <Button onClick={toggleDrawer("right", true)}>{"right"}</Button>
        <Drawer
          anchor={"right"}
          open={state["right"]}
          onClose={toggleDrawer("right", false)}
        >
          {list("right")}
        </Drawer>
      </Fragment>
    </>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 22:57:01