组件的重新渲染过多

时间:2021-07-30 14:12:43

标签: reactjs react-native react-hooks

我正在尝试调用一个组件,该组件在单击通知时显示通知的详细信息。但是,我不断收到重新渲染过多的错误。

这是我的通知代码 该组件调用数据库获取通知列表,然后将第一个通知设置为默认点击通知。

const Notification = (hospital) => {
const [users, setUsers] = useState([]);
  const [search, setSearch] = useState(null);
  const [status, setStatus] = useState(null);

    const [notifDetails, setNotification] = useState();

useEffect(async () => {
    await axios
      .get("/notifications")
      .then((res) => {
        const result = res.data;
        setUsers(result);
        setNotification(result[0]);
      })
      .catch((err) => {
        console.error(err);
      });
  }, []);
    return(
      <div className="hospital-notif-container">
         {filteredList(users, status, search).map((details, index) => {
              for (var i = 0; i < details.receiver.length; i++) {
                if (
                  (details.receiver[i].id === hospital.PK ||
                    details.receiver[i].id === "others") &&
                  details.sender.id !== hospital.PK
                ) {
                  return (
                    <div
                      className="hospital-notif-row"
                      key={index}
                      onClick={() => setNotification(details)}
                    >
                      <div className="hospital-notif-row">
                          {details.name}
                      </div>
                    </div>
                  );
                }
              }
              return null;
            })}
          </div>
          <NotificationDetails details={notifDetails} /> 
   );
}

对于通知详细信息:

当点击通知中的通知时会触发此功能。据说错误来自这个组件。

    const NotificationDetails = ({ details }) => {
  const [loading, setLoading] = useState(true);
useEffect(() => {
    if (Object.keys(details).length != 0) {
      setLoading(false);
    }
  }, [details]);
if (!loading) {
    return (
      <>
        <div className="hospital-details-container">
            <h2>{details.sender.name}</h2>
        </div>
     </>
    );
  } else {return (<div>Loading</div>);}
};

我应该怎么做才能限制重新渲染?我应该更改 useEffects 调用的第二个参数吗?还是我的组件中缺少某些东西?

我尝试从 NotificationDetails 调用 console.log ,它显示它正在无限渲染我在 axios 中设置的数据,即 result[0]。这是怎么回事?

1 个答案:

答案 0 :(得分:1)

您的问题应该出在 NotificationDetails 渲染中。你应该这样写:

const NotificationDetails = ({ details }) => {
    const [loading, setLoading] = useState(true);
    useEffect(() => {
       if (details.length != 0) {
         setLoading(false);
       }
    }, [details]);

    return (
      <div>
       {loading && 
          <div className="hospital-details-container">
            <div className="hospital-details-header">
              <h2>{details.sender.name}</h2>
            </div>
          </div>
       }
       {!loading && 
          <div>
             <ReactBootStrap.Spinner animation="border" />
          </div>
       }
      </div>
    );
  }

在条件语句外使用 return

编辑

现在我注意到您有一个异步 useEffect,它是一个反模式。您应该以这种方式修改您的 useEffect

 useEffect(() => {
    (async () => {
      await axios
        .get("/notifications")
        .then((res) => {
           const result = res.data;
           setUsers(result);
           setNotification(result[0]);
        })
        .catch((err) => {
           console.error(err);
        });
    })()
  }, []);