尝试过滤提取的数据库信息时出现卸载组件警告

Posted

技术标签:

【中文标题】尝试过滤提取的数据库信息时出现卸载组件警告【英文标题】:Unmounted component warning when trying to filter through pulled database information 【发布时间】:2021-08-06 15:45:27 【问题描述】:

我已经想出了如何从数据库中提取通知,但是在创建一个过滤器时遇到了问题,该过滤器允许提出问题的用户仅在他们的问题得到回答时才收到通知。

我编写的代码在第 31 行出现未安装错误,说明我执行过滤器的方式。这是错误消息:

无法对未安装的组件执行 React 状态更新。这是 无操作,但它表明您的应用程序中存在内存泄漏。修理, 在 useEffect 清理中取消所有订阅和异步任务 功能。

代码如下:

 import React,  useEffect, useState  from "react";
    import  makeStyles  from "@material-ui/core/styles";
    import Popper from "@material-ui/core/Popper";
    import NotificationsIcon from "@material-ui/icons/Notifications";
    import "../Style/Header.css";
    import db,  auth  from "../firebase";
    
    const useStyles = makeStyles((theme) => (
      paper: 
        border: "1px solid",
        padding: theme.spacing(1),
        backgroundColor: theme.palette.background.paper,
        zIndex: "10",
      ,
    ));
    
    
    export default function SimplePopper() 
          const classes = useStyles();
          const [anchorEl, setAnchorEl] = React.useState(null);
          const [notifications, setNotifications] = useState([]);
        
          const handleClick = (event) => 
            setAnchorEl(anchorEl ? null : event.currentTarget);
          ;
        
          const open = Boolean(anchorEl);
          const id = open ? "simple-popper" : undefined;
        
           useEffect(() => 
    let mounted = true;
    db.collection("notifications")
      .where(auth.askerUserId, "==", auth.currentUser.uid)
      .orderBy("timestamp", "desc")
      .onSnapshot((snapshot) => 
        if (mounted) 
          setNotifications(
            snapshot.docs.map((doc) => (
              id: doc.id,
              content: doc.data().content,
            ))
          );
        
      );
    return () => (mounted = false);
  , []);
        
          return (
            <div className="header__icon">
              <NotificationsIcon
                aria-describedby=id
                type="button"
                onClick=handleClick
              />
              <Popper id=id open=open anchorEl=anchorEl style= zIndex: 100 >
                <div className=classes.paper>
                  <ul className="notifications">
                    notifications.map((notification) => (
                      <li key=notification.id>notification.content</li>
                    ))
                  </ul>
                </div>
              </Popper>
            </div>
          );
        

【问题讨论】:

【参考方案1】:

当组件被卸载时你应该取消订阅:

import React,  useEffect, useState  from "react";
    import  makeStyles  from "@material-ui/core/styles";
    import Popper from "@material-ui/core/Popper";
    import NotificationsIcon from "@material-ui/icons/Notifications";
    import "../Style/Header.css";
    import db,  auth  from "../firebase";
    
    const useStyles = makeStyles((theme) => (
      paper: 
        border: "1px solid",
        padding: theme.spacing(1),
        backgroundColor: theme.palette.background.paper,
        zIndex: "10",
      ,
    ));
    
    
    export default function SimplePopper() 
          const classes = useStyles();
          const [anchorEl, setAnchorEl] = React.useState(null);
          const [notifications, setNotifications] = useState([]);
        
          const handleClick = (event) => 
            setAnchorEl(anchorEl ? null : event.currentTarget);
          ;
        
          const open = Boolean(anchorEl);
          const id = open ? "simple-popper" : undefined;
        
           useEffect(() => 
    let mounted = true;
    let unsub=db.collection("notifications")
      .where(auth.askerUserId, "==", auth.currentUser.uid)
      .orderBy("timestamp", "desc")
      .onSnapshot((snapshot) => 
        if (mounted) 
          setNotifications(
            snapshot.docs.map((doc) => (
              id: doc.id,
              content: doc.data().content,
            ))
          );
        
      );
    return () => unsub();
  , []);
        
          return (
            <div className="header__icon">
              <NotificationsIcon
                aria-describedby=id
                type="button"
                onClick=handleClick
              />
              <Popper id=id open=open anchorEl=anchorEl style= zIndex: 100 >
                <div className=classes.paper>
                  <ul className="notifications">
                    notifications.map((notification) => (
                      <li key=notification.id>notification.content</li>
                    ))
                  </ul>
                </div>
              </Popper>
            </div>
          );
        

【讨论】:

我已经实施了您的更改,但仍然没有更改 添加 .where(auth.askerUserId, "==", auth.currentUser.uid) 后似乎出现了错误,我认为该错误与我的调用方式有关 我通过在“user.askerUserId”周围添加引号来消除错误。我认为您的解决方案对我有用。

以上是关于尝试过滤提取的数据库信息时出现卸载组件警告的主要内容,如果未能解决你的问题,请参考以下文章

JS 数据表 |获取数据时出现未知警告

使用 Facebook Graph API 提取用户信息时出现身份验证错误

卸载drupal 8 commerce时出现意外错误

访问从 Reactjs 中的状态创建的数组的数据时出现问题

在 MATLAB 中使用回归函数时出现排名不足警告

构建 Vue 项目时出现错误“无法安装组件:未定义模板或渲染函数”