如下面的代码所示,我正在使用useEffect挂钩来监视对百分比变量的更改,然后设置一个计时器以在1秒内递增该变量。页面加载后,就会立即执行回调。
percent变量用于呈现折线图,该折线图将递增,直到达到传递的值为止。 (它基本上显示了合格率%,但是在加载时,条形图将在屏幕上移动到其%。)
一切正常,但是控制台标记最大更新深度警告,指出当我在useEffect中使用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;
感谢您的帮助
答案 0 :(得分:4)
在timer = 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;