如下面的代码所示,我正在使用useEffect钩子来监视对百分比变量的更改,然后设置一个计时器以在1秒内递增该变量。回调将在页面加载后立即发生,从而启动该过程。
百分比变量用于呈现折线图,该折线图递增,直到达到传递的值。(它基本上显示 % 通过率,但在加载时,条形将在屏幕上移动,直到其 %。
一切正常,但控制台标记最大更新深度警告,指出当我在 useImpact 中使用 setState 时,它试图防止无限循环。我明白这一点,但我知道我永远不会传入超过 100 的值,因此永远不会有无限循环。我还需要递归功能来让我的图表显示动态填充。
即使我决定忽略该警告,如果我挂载组件,也会在我的测试中产生错误。
有没有办法告诉反应,这不会是一个无限循环并让错误消失?还是我需要不同的方法?
const ReportProgressSummary = ({result, title}) => {
const [percent, setPercent] = useState(0);
let timer = null;
useEffect( () => {
let newPercent = percent + 1;
if (newPercent > result) {
clearTimeout(timer);
return;
}
timer = setTimeout(setPercent(newPercent), 1000);
}, [percent]);
return (
<ContainerStyled>
<ChartContainerStyled>
<ChartTitleStyled>{title}</ChartTitleStyled>
<CheckboxStyled type="checkbox" />
</ChartContainerStyled>
<ChartContainerStyled>
<LineContainerStyled>
<Line trailWidth="2" trailColor="red" strokeWidth="4" strokeColor="green" percent={percent}/>
</LineContainerStyled>
<h6>{percent}%</h6>
</ChartContainerStyled>
</ContainerStyled>
)
};
export default ReportProgressSummary;
感谢您的任何帮助
Intimer = setTimeout(setPercent(newPercent), 1000);
setPercent(newPercent)
将立即致电。setTimeout 需要一个函数(而不是函数调用(:
timer = setTimeout(() => setPercent(newPercent), 1000);
要记住的另一件事是,timer
将在每次渲染时定义,因此clearTimeout
不会产生任何影响。为避免这种情况,您可以创建一个 ref,以便记住该值。这样:
const timer = React.useRef()
使用/设置值是对current
属性完成
timer.current = ...
工作示例:
const ReportProgressSummary = ({result, title}) => {
const [percent, setPercent] = useState(0);
const timer = React.useRef();
useEffect( () => {
let newPercent = percent + 1;
if (newPercent > result) {
clearTimeout(timer.current);
return;
}
timer.current = setTimeout(() => setPercent(newPercent), 1000);
}, [percent]);
return (
<ContainerStyled>
<ChartContainerStyled>
<ChartTitleStyled>{title}</ChartTitleStyled>
<CheckboxStyled type="checkbox" />
</ChartContainerStyled>
<ChartContainerStyled>
<LineContainerStyled>
<Line trailWidth="2" trailColor="red" strokeWidth="4" strokeColor="green" percent={percent}/>
</LineContainerStyled>
<h6>{percent}%</h6>
</ChartContainerStyled>
</ContainerStyled>
)
};
export default ReportProgressSummary;