我有两个组件:通知和通知详细信息。通知是通知列表,而另一个组件显示所选通知的详细信息(单击时)。我已经了解了反模式并为我的异步 useEffect 钩子执行了它。但是,我的渲染仍然出现无限循环。
const Notification = (hospital) => {
const [notifDetails, setNotification] = useState([]);
const [users, setUsers] = useState([]);
const [search, setSearch] = useState(null);
const [status, setStatus] = useState(null);
useEffect(() => {
const getNotif = async () => {
await axios
.get("/notifications")
.then((res) => {
const result = res.data.Item;
setUsers(result);
setNotification(result[0]);
console.log(notifDetails);
})
.catch((err) => {
console.error(err);
});
};
getNotif();
}, []);
return (
<div>
{filteredList(users, status, search).map((details, index) => {
for (var i = 0; i < details.receiver.length; i++) {
if (
(details.receiver[i].receiver_id === hospital.PK ||
details.receiver[i].receiver_id === "others") &&
details.sender.sender_id !== hospital.PK
) {
return (
<div
className="hospital-notif-row"
tabIndex={index}
key={index}
onClick={() => setNotification(details)}
>
<div className="hospital-notif-row-col hospital-notif-row-col-left">
<span className="hospital-notif-name">
{details.sender.sender_name}
</span>
<span className="hospital-notif">
{details.notif_type}
</span>
<span className="hospital-urgency">
{details.urgency}
</span>
</div>
<div className="hospital-notif-row-col hospital-notif-row-col-right">
<span className="hospital-notif-time">
{details.time}
</span>
</div>
</div>
);
}
}
return null;
})}
</div>
<NotificationDetails details={notifDetails} />
);
对于通知详细信息:
const NotificationDetails = ({ details }) => {
const [loading, setLoading] = useState(true);
const [message, setMessage] = useState("");
const [question, setQuestion] = useState("");
console.log(details); // <-- SHOWS THE INFINITE PRINTING
useEffect(() => {
if (details.length != 0 && loading === true) {
setLoading(false);
}
}, [details]);
return (
<>
{!loading && (
<div className="hospital-details-container">
<div className="hospital-details-header">
<h2>{details.sender.sender_name}</h2>
</div>
</div>
)}
{loading && (
<div>
<ReactBootStrap.Spinner animation="border" />
</div>
)}
</>
);
我编辑了我的代码,以便加载将在通知中
const Notification = (hospital) => {
const [notifDetails, setNotification] = useState([]);
const [users, setUsers] = useState([]);
const [search, setSearch] = useState(null);
const [status, setStatus] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
axios
.get("/notifications")
.then((res) => {
const result = res.data.Item;
setUsers(result);
setNotification(result[0]);
setLoading(false);
console.log(notifDetails);
})
.catch((err) => {
console.error(err);
});
}, []);
const filteredList = (users, status, search) => {
return users
.filter((user) => byStatus(user, status))
.filter((user) => bySearch(user, search));
};
return (
<div className="container-w-nav container-notif">
<div className="hospital-container">
<div className="hospital-info">
<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].receiver_id === hospital.PK ||
details.receiver[i].receiver_id === "others") &&
details.sender.sender_id !== hospital.PK
) {
return (
<div
className="hospital-notif-row"
tabIndex={index}
key={index}
onClick={() => setNotification(details)}
>
<div className="hospital-notif-row-col hospital-notif-row-col-left">
<span className="hospital-notif-name">
{details.sender.sender_name}
</span>
</div>
</div>
);
}
}
return null;
})}
</div>
</div>
{/* Notification Details Component */}
<div className="hospital-details-container">
{!loading && <NotificationDetails details={notifDetails} />}
{loading && <ReactBootStrap.Spinner animation="border" />}
</div>
</div>
</div>
);
};
对于通知详细信息:(我删除了 useEffect)
const NotificationDetails = ({ details }) => {
const [message, setMessage] = useState("");
const [question, setQuestion] = useState("");
return (
<>
<div className="hospital-details-header">
<img
className="hospital-details-header-image"
src={logo}
alt="Hospital Logo"
/>
<h2>{details.sender.sender_name}</h2>
</div>
</>
);