Javascript 当不同的浏览器选项卡处于活动状态时,使用中函数的行为有效
我有个奇怪的问题。 我创建了一个函数,旨在60秒后重置Linearprogress元素Javascript 当不同的浏览器选项卡处于活动状态时,使用中函数的行为有效,javascript,reactjs,material-ui,use-effect,Javascript,Reactjs,Material Ui,Use Effect,我有个奇怪的问题。 我创建了一个函数,旨在60秒后重置Linearprogress元素 useEffect(() => { const interval2 = setInterval(() => { var internal = timer if( internal < 100 ) {internal = (internal - (1.695 * -1 )) } else {internal = internal - 100}
useEffect(() => {
const interval2 = setInterval(() => {
var internal = timer
if( internal < 100 ) {internal = (internal - (1.695 * -1 )) } else {internal = internal - 100}
setTimer(internal)
}, 1000)
return () => clearInterval(interval2)
}, [timer])
useffect(()=>{
const interval2=setInterval(()=>{
内部变量=计时器
if(internal<100){internal=(internal-(1.695*-1))}else{internal=internal-100}
设置计时器(内部)
}, 1000)
return()=>clearInterval(间隔2)
},[计时器])
然后,我有一个线性进度元素的渲染,如下所示:
return (
<div>
<LinearProgress
color ="secondary"
value={timer}
variant="determinate"
/>
</div>
);
返回(
);
现在奇怪的部分是:当我看我的应用程序时,一切看起来都很正常,60秒后,该条重新设置为开始,然后重复。但是,当我在浏览器中改变活动标签之后,在55秒内返回(栏应该在末端附近)-条在中间。< /P>
当应用程序的选项卡处于非活动状态时,useeffect似乎不会像应该的那样频繁地重新执行该功能
我错过了什么
代码沙箱(此处复制了问题):
谢谢您的
设置间隔
导致内存泄漏。
每1000毫秒,它将重新运行,但同时,useffect
也会由setTimer(内部)触发代码>。因此,您有越来越多的设置间隔运行
一种解决方案是添加clearInterval(interval2)在更新计时器之前执行code>
但从概念上讲,它并不完美,因为我们使用的是一个间隔作为超时,因此您可以将setInterval
替换为setTimeout
,并在返回时将clearInterval
替换为clearTimeout
,而无需修改任何其他内容
以下是经过修改的代码的工作版本,以及:
嘿,我理解这个问题,但是无法按照您的建议通过更改代码来解决。为什么只有在tab没有聚焦的情况下泄漏才会显现出来?你能告诉我你是否可以在我添加到我的答案中的沙箱中重现这个问题吗?我试过了,但无法复制。我猜测,当选项卡重新获得焦点时出现的问题可能是由于浏览器的某些内存管理(在用户不查看选项卡时限制某些渲染)。是的,问题仍然存在。在17:54时打开应用程序,将标签改为我的脸谱网,在17:54:55返回,酒吧显示计时器=50(中间的进度条)-正如我所说的问题不会发生在我的活动选项卡是沙箱。你能复制吗?刚才你说你不能复制。。。。谢谢我尝试了一个稍微不同的版本,发现我也有错误(但我认为这不是因为internal=internal-1.695*-1;
。我在stackoverflow上发现了同样的问题。解决方法是使用requestAnimationFrame
。我不知道代码的上下文,但如果您只想填充一行并在填充完毕后重置它,您只能使用。我更新了answ。)呃,用这个信息。
import React from "react";
import PropTypes from "prop-types";
import { makeStyles } from "@material-ui/styles";
import { LinearProgress } from "@material-ui/core";
import { useEffect } from "react";
const TotalProfit = (props) => {
const [timer, setTimer] = React.useState(0);
useEffect(() => {
const interval2 = setTimeout(() => {
var internal = timer;
if (internal < 100) {
internal = internal - 1.695 * -1;
} else {
internal = internal - 100;
}
setTimer(internal);
}, 1000);
return () => clearTimeout(interval2);
}, [timer]);
return (
<div>
<div>{timer}</div>
<LinearProgress color="secondary" value={timer} variant="determinate" />
</div>
);
};
TotalProfit.propTypes = {
className: PropTypes.string
};
export default TotalProfit;
import React, { useEffect, useState } from "react";
import PropTypes from "prop-types";
import { makeStyles } from "@material-ui/styles";
import { LinearProgress } from "@material-ui/core";
const TotalProfit = (props) => {
const [timer] = useState(Date.now()/1000);
const [delta, setDelta] = useState(0);
useEffect(() => {
const interval2 = setInterval(() => {
setDelta((Date.now()/1000 - timer) % 100);
}, 1000);
return () => clearInterval(interval2);
}, [timer]);
return (
<div>
<div>{delta}</div>
<LinearProgress color="secondary" value={delta} variant="determinate" />
</div>
);
};
TotalProfit.propTypes = {
className: PropTypes.string
};
export default TotalProfit;