Reactjs React Hooks:Carousel autoplay,直到单击一个按钮,然后don';t完成最后剩余的setTimeout()

Reactjs React Hooks:Carousel autoplay,直到单击一个按钮,然后don';t完成最后剩余的setTimeout(),reactjs,settimeout,react-hooks,Reactjs,Settimeout,React Hooks,我在做一种旋转木马 function CareersReasonsCarousel(props) { const [current, setCurrent] = useState(0); const [dir, setDir] = useState("next"); const [auto, setAuto] = useState(true); const move = (pos) => { setAuto(false);

我在做一种旋转木马

function CareersReasonsCarousel(props) {
    const [current, setCurrent] = useState(0);
    const [dir, setDir] = useState("next");
    const [auto, setAuto] = useState(true);

    const move = (pos) => {
        setAuto(false);
        setCurrent(current+pos);
    }

    useEffect(() => {
        setTimeout(() => {
            if (auto) {
                setCurrent(current+1);
            }
        }, 5000);
    }, [current]);
}
下面,在我的
返回中,我有

<div className="arrow next" onClick={ () => { move(1) }}><img src={ arrow_right } alt="" /></div>
{move(1)}}>
我希望旋转木马在首次加载页面时从自动播放开始,在有人单击“下一步”或“上一步”箭头时失去自动播放。问题是,它的设置方式,当我单击箭头时,旋转木马仍将等待剩余的5秒延迟,并执行它已注册的最后一个“设置超时”,只有到那时它才会看到
auto
false
,并且不再需要自动执行

我如何让它验证
auto
的值,不是在注册setTimeout时,而是在应该执行setTimeout时(在5秒延迟后)


谢谢大家!

您需要更新
useffect
依赖项数组,使其引用
auto
的当前值,而不是上一次渲染中的值。如果需要,在重新运行效果时,还需要在前一个计时器上调用
clearTimeout
,如果您的组件被卸载,通常最好返回清理功能,以避免内存泄漏

const timerRef = useRef(null)

useEffect(() => {
    if(timerRef.current){
        clearTimeout(timerRef.current);
    }
    timerRef.current = setTimeout(() => {
        if (auto) {
            setCurrent(c=>c+1);
        }
    }, 5000);
    return ()=>clearTimeout(timerRef.current);
}, [auto, current]);

我试过你的建议,但还是一样。假设我看到滑动开关,2秒后单击“下一步”,3秒后它会自动切换最后一次,然后注册
auto===false
。问题似乎出在setTimeout()上,我一定不明白作用域的某些方面。哇,它成功了!老实说,我不知道useRef()是如何工作的,但我会找到更多关于它的教程!我准备使用一个每100毫秒递增一次的计时器,每次都验证
auto
。我很高兴我不用依赖这样一个笨拙的解决方案。非常感谢!没问题。。。useRef只是一个可变对象,您可以使用它在渲染之间保存内容-您可以使用
.current
访问与当前渲染相关的引用-在本例中,是对计时器的引用。通过在这里使用它,我们可以取消旧计时器,并在效果运行时创建一个新计时器。没有它,对原始超时的引用将在后续渲染中丢失,因此无法清除。这是一个很长但很好的解释: