使用 React hooks 和 setInterval 的幻灯片

Slideshow using React hooks and setInterval

我正在尝试使用 React Hooks 和 setInterval 制作包含 5 张图片的幻灯片。

所以当计数器到达照片 5(索引 4)时,它返回到照片 1(索引 0)。

计数器看起来没问题,但是当 if 语句中的条件为假时,计数器会一直计数到 4。

import React, { useState, useEffect } from 'react';
import { photoSource } from './photo-source.js';

 function Slideshow() {

const [imgSource, setImgSource] = useState(0);

useEffect(() => {
  const intervalId = setInterval(() => {
          if (imgSource <= 1) {
            setImgSource(imgSource => imgSource + 1);
          } else {
            setImgSource(0);
                }
          }, 10000);
    return () => clearInterval(intervalId);
}, []);

console.log('ImgSource: ' + imgSource);
console.log(imgSource <= 1)
console.log(photoSource[imgSource].src)

记录到控制台的所有值似乎都是正确的,唯一明显的问题是计数器一直在计数,就好像 if 语句不起作用一样。

这里有两个问题。 First 很小:条件应该是 imgSource < 4,而不是 imgSource <= 1。其次,更重要的是,setImgSource 之外的 imgSource 的值被锁定在调用 setInterval 时的值(锁定为零)。因此,条件始终为真,因为 imgSource0,并且该值继续递增超过目标最大值 4

有几种方法可以处理这个问题,其中最简单的方法是在 setImgSource 回调中执行检查,因为它可以访问 imgSource 的当前值。

例如:

useEffect(() => {
        const intervalId = setInterval(() => {
            setImgSource((imgSource) => {
                if (imgSource < 4) {
                    return imgSource + 1;
                }
                return 0;
            });
        }, 10000);
        return () => clearInterval(intervalId);
    }, []);

尽管您可以使用 %(余数)运算符删除一些代码,如下所示:

useEffect(() => {
        const intervalId = setInterval(() => {
            setImgSource((imgSource) => (imgSource + 1) % 5);
        }, 1000);
        return () => clearInterval(intervalId);
    }, []);

请注意,在 JavaScript 中,% 运算符计算余数,而不是 modulus。这两个对于正数是相同的,所以这种方法会起作用,因为你只是递增 imgSource。如果您希望幻灯片放映改变方向,您必须做更多的工作才能使相同的方法起作用,这里有一个 mod 函数:

export function mod(n, m) {
    return ((n % m) + m) % m;
}

你可以这样使用:

setImgSource(prev => mod(prev + 1, 5));