如何避免 ReactJS 中屏幕尺寸变化时的内存泄漏
在Google Inspector中,在桌面和移动视图之间切换时,我会不断遇到内存泄漏错误(尽管如果我通过伸展而收缩/扩展屏幕)。错误消息是:
我不使用我知道的任何订阅或异步任务。我唯一能想到的可能会导致这件事,是在屏幕切换时,我的AlertDialog组件没有显示。那是因为它只是有条件地渲染的:
return (
<Screen>
{showDialog === true ?
<AlertDialog /> :
<MainApp />
}
</Screen>
);
如果更改时屏幕上的AlertDialog在屏幕上,则不会显示错误。
我的对话框的代码是:
import { useEffect, useState } from "react";
import { useWindowSize } from "src/hooks";
import Dialog from '@mui/material/Dialog';
import DialogActions from '@mui/material/DialogActions';
import DialogContent from '@mui/material/DialogContent';
import DialogContentText from '@mui/material/DialogContentText';
import DialogTitle from '@mui/material/DialogTitle';
const AlertDialog = (props : any) => {
const {innerWidth, innerHeight} = useWindowSize();
const [openDialog, setOpenDialog] = useState(true);
const [buttonStyle, setButtonStyle] = useState({});
useEffect( () => { // Needs b/c isn't working right in Styled
setButtonStyle({
width: Math.max(innerWidth/10, 100),
});
}, [innerWidth, innerHeight])
const handleClick = (choseTrue : boolean) => {
setOpenDialog(false);
props.onClick(choseTrue);
}
return (
<Dialog
open={openDialog}
onClose={() => null} // Use null to prevent it from closing until an option is chosen
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
>
<DialogTitle id="alert-dialog-title" style={{textAlign: "center"}}>{"Set Device"}</DialogTitle>
<DialogContent>
<DialogContentText id="alert-dialog-description"> </DialogContentText>
</DialogContent>
<DialogActions>
<button onClick={() => handleClick(true)} style={buttonStyle}>{props.choiceTrue}</button>
<button onClick={() => handleClick(false)} style={buttonStyle}>{props.choiceFalse}</button>
</DialogActions>
</Dialog>
);
};
export default AlertDialog;
这是我的屏幕调整大小。我很确定这是问题的来源,因为如果我在AlertDialog中评论usewindowsize
行,没有错误:
import { useState, useEffect } from "react";
export const useWindowSize = () => {
const [size, setSize] = useState<{
innerWidth: number;
innerHeight: number;
}>({ ...window });
useEffect(() => {
const cb = (u: UIEvent) => {
const w = u.target as Window;
setSize({ ...w });
};
window.addEventListener("resize", cb, true);
() => window.removeEventListener("resize", cb);
}, []);
return size;
};
为什么我会遇到此内存泄漏错误,以及如何避免它?
I keep getting memory leak errors when switching between desktop and mobile view in google inspector (though not if I shrink/expand the screen by stretching). The error message is:
I'm not using any subscriptions or asynchronous tasks I'm aware of. The only thing I can think of that might contribute to this is that at the time of the screen switching, my AlertDialog component isn't showing. That's because it's only conditionally rendered:
return (
<Screen>
{showDialog === true ?
<AlertDialog /> :
<MainApp />
}
</Screen>
);
The error doesn't show up if the AlertDialog is on screen at the time of the change.
The code for my dialog is:
import { useEffect, useState } from "react";
import { useWindowSize } from "src/hooks";
import Dialog from '@mui/material/Dialog';
import DialogActions from '@mui/material/DialogActions';
import DialogContent from '@mui/material/DialogContent';
import DialogContentText from '@mui/material/DialogContentText';
import DialogTitle from '@mui/material/DialogTitle';
const AlertDialog = (props : any) => {
const {innerWidth, innerHeight} = useWindowSize();
const [openDialog, setOpenDialog] = useState(true);
const [buttonStyle, setButtonStyle] = useState({});
useEffect( () => { // Needs b/c isn't working right in Styled
setButtonStyle({
width: Math.max(innerWidth/10, 100),
});
}, [innerWidth, innerHeight])
const handleClick = (choseTrue : boolean) => {
setOpenDialog(false);
props.onClick(choseTrue);
}
return (
<Dialog
open={openDialog}
onClose={() => null} // Use null to prevent it from closing until an option is chosen
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
>
<DialogTitle id="alert-dialog-title" style={{textAlign: "center"}}>{"Set Device"}</DialogTitle>
<DialogContent>
<DialogContentText id="alert-dialog-description"> </DialogContentText>
</DialogContent>
<DialogActions>
<button onClick={() => handleClick(true)} style={buttonStyle}>{props.choiceTrue}</button>
<button onClick={() => handleClick(false)} style={buttonStyle}>{props.choiceFalse}</button>
</DialogActions>
</Dialog>
);
};
export default AlertDialog;
This is my screen resize code. I'm pretty sure it's the source of the issue, since if I comment out the useWindowSize
line in AlertDialog, there is no error:
import { useState, useEffect } from "react";
export const useWindowSize = () => {
const [size, setSize] = useState<{
innerWidth: number;
innerHeight: number;
}>({ ...window });
useEffect(() => {
const cb = (u: UIEvent) => {
const w = u.target as Window;
setSize({ ...w });
};
window.addEventListener("resize", cb, true);
() => window.removeEventListener("resize", cb);
}, []);
return size;
};
Why am I getting this memory leak error, and how can I avoid it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你需要从 useEffect 返回该清理函数的回调函数我之前已经写过这个钩子,这里是代码
如果你想要 useScreenSizeChecker Hook,
you need to return the callback function from useEffect for that cleanup function
if you want to have useScreenSizeChecker Hook I have written this hook before here is the code