useEffect 被意外触发
useEffect is trigged unexpectedly
意外调用了 useEffect 挂钩。一旦计时器达到零并且当我将其设置为 10(使用重新发送 Otp 按钮)时,计时器开始减少的速度快于 1 秒。
我的组件如下:
const EnterOtpView = ({ touched, errors, isSubmitting }) => {
const [timer, setTimer] = useState(3);
useEffect(() => {
if (timer > 0) {
setInterval(() => setTimer((prevTimer) => prevTimer - 1), 1000);
}
}, [timer]);
return (
<div>
{timer > 0 ? (
<p>Resend Otp in: {timer} seconds</p>
) : (
<button
type='button'
className='btn btn-link'
onClick={() => setTimer(10)}
>
resend otp
</button>
)}
</div>
);
};
我尝试过的:
- 从 useEffect 的依赖数组中删除了定时器
- 创建一个单独的函数来减少计时器
如有任何帮助,我们将不胜感激。
对我有用的解决方案:
useEffect(() => {
setInterval(() => setTimer((prevTimer) => prevTimer - 1), 1000);
}, []);
我只是像上面那样改变了 useEffect,即将它变成了 useEffect 的 componentDidMount 形式,现在它可以正常工作了。
从 useEffect 中删除 "timer" 依赖项..
每次都会调用这个函数
这是一个工作示例,说明如何设置一次间隔,防止它变为负数,并在卸载时清除它:
const {useState, useEffect} = React;
const Example = () => {
const [timer, setTimer] = useState(3);
useEffect(() => {
// setInterval returns the id of the interval so we can clear it later
const id = setInterval(() => {
setTimer((prevTimer) => {
// Move our negative logic inside the functional update
if (prevTimer > 0) {
return prevTimer - 1;
}
return 0;
})}, 1000);
// Clear the interval on umount
return () => {
clearInterval(id);
}
}, []);
return (
<div>
{timer > 0 ? (
<p>Resend Otp in: {timer} seconds</p>
) : (
<button
type='button'
className='btn btn-link'
onClick={() => setTimer(10)}
>
resend otp
</button>
)}
</div>
);
}
ReactDOM.render(<Example />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>
意外调用了 useEffect 挂钩。一旦计时器达到零并且当我将其设置为 10(使用重新发送 Otp 按钮)时,计时器开始减少的速度快于 1 秒。
我的组件如下:
const EnterOtpView = ({ touched, errors, isSubmitting }) => {
const [timer, setTimer] = useState(3);
useEffect(() => {
if (timer > 0) {
setInterval(() => setTimer((prevTimer) => prevTimer - 1), 1000);
}
}, [timer]);
return (
<div>
{timer > 0 ? (
<p>Resend Otp in: {timer} seconds</p>
) : (
<button
type='button'
className='btn btn-link'
onClick={() => setTimer(10)}
>
resend otp
</button>
)}
</div>
);
};
我尝试过的:
- 从 useEffect 的依赖数组中删除了定时器
- 创建一个单独的函数来减少计时器
如有任何帮助,我们将不胜感激。
对我有用的解决方案:
useEffect(() => {
setInterval(() => setTimer((prevTimer) => prevTimer - 1), 1000);
}, []);
我只是像上面那样改变了 useEffect,即将它变成了 useEffect 的 componentDidMount 形式,现在它可以正常工作了。
从 useEffect 中删除 "timer" 依赖项..
每次都会调用这个函数
这是一个工作示例,说明如何设置一次间隔,防止它变为负数,并在卸载时清除它:
const {useState, useEffect} = React;
const Example = () => {
const [timer, setTimer] = useState(3);
useEffect(() => {
// setInterval returns the id of the interval so we can clear it later
const id = setInterval(() => {
setTimer((prevTimer) => {
// Move our negative logic inside the functional update
if (prevTimer > 0) {
return prevTimer - 1;
}
return 0;
})}, 1000);
// Clear the interval on umount
return () => {
clearInterval(id);
}
}, []);
return (
<div>
{timer > 0 ? (
<p>Resend Otp in: {timer} seconds</p>
) : (
<button
type='button'
className='btn btn-link'
onClick={() => setTimer(10)}
>
resend otp
</button>
)}
</div>
);
}
ReactDOM.render(<Example />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>