Javascript 数组长度的setInterval

Javascript 数组长度的setInterval,javascript,reactjs,Javascript,Reactjs,我正在尝试为状态中的数组长度设置间隔。 数组eventDate的长度为4,因此函数应该返回0、1、2、3,然后返回0。 以下是我到目前为止的情况: const[eventDateIndex,setEventDateIndex]=useState(0); 常量索引时间=()=>{ setEventDateIndex(eventDateIndex+1) }; const time=eventDate[eventDateIndex] useffect(()=>{ if(eventDateIndex==

我正在尝试为状态中的数组长度设置间隔。
数组
eventDate
的长度为4,因此函数应该返回0、1、2、3,然后返回0。

以下是我到目前为止的情况:

const[eventDateIndex,setEventDateIndex]=useState(0);
常量索引时间=()=>{
setEventDateIndex(eventDateIndex+1)
};
const time=eventDate[eventDateIndex]
useffect(()=>{
if(eventDateIndex==eventDate.length){
setEventDateIndex(0)
}
console.log(eventDateIndex)
常数id=设置间隔(indexTimer,2000);
return()=>clearInterval(id);
},[eventDateIndex]);
但是,控制台返回0、1、2、3,然后返回4,然后再返回0。
我知道这与indexTimer在使用效果之前的运行方式有关,但我无法理解。有人能帮我吗?

索引是基于0的。你需要改变

if (eventDateIndex === eventDate.length) {
    setEventDateIndex(0)
  }


索引是基于0的。你需要改变

if (eventDateIndex === eventDate.length) {
    setEventDateIndex(0)
  }


函数
eventDate.length
返回数组的长度,在您的示例中为4,但您希望转到3,因此此代码:

if(eventDateIndex==eventDate.length){
setEventDateIndex(0)
}
可以这样写:

if(eventDateIndex>=(eventDate.length-1)){
setEventDateIndex(0)
}

函数
eventDate.length
返回数组的长度,在您的示例中为4,但您希望转到3,因此此代码:

if(eventDateIndex==eventDate.length){
setEventDateIndex(0)
}
可以这样写:

if(eventDateIndex>=(eventDate.length-1)){
setEventDateIndex(0)
}

您应该只创建一次间隔计时器:

function YourComponent({ eventDate }) {
  const tickId = useRef(null);
  const [eventIndex, setEventIndex] = useState(0);

  useEffect(() => {
    // If the array length changes we want to clear the old interval.
    clearInterval(tickId.current);

    tickId.current = setInterval(() => {
      setEventIndex(i => (i <= eventDate.length - 2 ? i + 1 : 0));
    }, 2000);

    return () => clearInterval(tickId.current);
  }, [setEventIndex, eventDate.length]);

  return (
    <div>Event date: {eventDate[eventIndex]}</div>
  );
}
函数组件({eventDate}){
常量tickId=useRef(null);
const[eventIndex,setEventIndex]=useState(0);
useffect(()=>{
//如果数组长度更改,我们希望清除旧的间隔。
clearInterval(滴答当前);
tickId.current=setInterval(()=>{
setEventIndex(i=>(i clearInterval(tickId.current));
},[setEventIndex,eventDate.length]);
返回(
事件日期:{eventDate[eventIndex]}
);
}
演示:


使用
tickId
的额外复杂性是确保在阵列长度发生变化时删除旧计时器。

您应该只创建一次间隔计时器:

function YourComponent({ eventDate }) {
  const tickId = useRef(null);
  const [eventIndex, setEventIndex] = useState(0);

  useEffect(() => {
    // If the array length changes we want to clear the old interval.
    clearInterval(tickId.current);

    tickId.current = setInterval(() => {
      setEventIndex(i => (i <= eventDate.length - 2 ? i + 1 : 0));
    }, 2000);

    return () => clearInterval(tickId.current);
  }, [setEventIndex, eventDate.length]);

  return (
    <div>Event date: {eventDate[eventIndex]}</div>
  );
}
函数组件({eventDate}){
常量tickId=useRef(null);
const[eventIndex,setEventIndex]=useState(0);
useffect(()=>{
//如果数组长度更改,我们希望清除旧的间隔。
clearInterval(滴答当前);
tickId.current=setInterval(()=>{
setEventIndex(i=>(i clearInterval(tickId.current));
},[setEventIndex,eventDate.length]);
返回(
事件日期:{eventDate[eventIndex]}
);
}
演示:


tickId
的额外复杂性是确保在数组长度发生变化时删除旧计时器。

这是因为您的代码中存在一个小缺陷。以下是您尝试实现的工作版本

const eventDate = ["12/21/2019", "12/20/2019", "12/31/2019"];
    const [eventDateIndex, setEventDateIndex] = useState(0);

    const indexTimer = () => {
        if (eventDateIndex != eventDate.length - 1) setEventDateIndex(eventDateIndex + 1);
        else setEventDateIndex(0);
    };

    const time = eventDate[eventDateIndex];

    useEffect(() => {
        console.log(eventDateIndex);
        const id = setInterval(indexTimer, 2000);
        return () => clearInterval(id);
    }, [eventDateIndex]);

    return null;

这是因为您的代码中存在一个小缺陷。以下是您试图实现的工作版本

const eventDate = ["12/21/2019", "12/20/2019", "12/31/2019"];
    const [eventDateIndex, setEventDateIndex] = useState(0);

    const indexTimer = () => {
        if (eventDateIndex != eventDate.length - 1) setEventDateIndex(eventDateIndex + 1);
        else setEventDateIndex(0);
    };

    const time = eventDate[eventDateIndex];

    useEffect(() => {
        console.log(eventDateIndex);
        const id = setInterval(indexTimer, 2000);
        return () => clearInterval(id);
    }, [eventDateIndex]);

    return null;

尝试使用setTimeout递归。听起来你的代码确实在加速。这有各种各样的问题,比如设置setInterval(一个新的间隔)每次eventDateIndex更改时。代码应该简单得多,以实现相同的结果-您希望每2秒递归递增一个计数器以计算数组的长度?@Dominic eventDateIndex只设置一次,不应更改。我在useEffect中使用它的原因是因为我需要等待eventDateIndex设置(虽然在我写这篇文章的时候,我觉得我编写这篇文章真的很愚蠢)尝试使用setTimeout递归。这听起来确实像是你的代码在加速。这有各种各样的问题,比如设置setInterval(一个新的间隔)每次eventDateIndex更改时。代码应该简单得多,以实现相同的结果-您希望每2秒递归递增一个计数器以计算数组的长度?@Dominic eventDateIndex只设置一次,不应更改。我在useEffect中使用它的原因是因为我需要等待eventDateIndex设置(虽然在我写这篇文章的时候,我觉得我编写这篇文章真的很愚蠢)我以前试过,它在控制台中返回,但3没有超时-返回3然后直接返回到0我已将上述问题的答案作为另一个答案发布。请检查并采取相应行动。谢谢我以前试过,它在控制台中返回,但3没有超时-返回3然后直接返回到0我已发布了答案to将上述问题作为另一个答案。请检查并采取相应的行动。感谢将此情况作为另一个答案发生-返回控制台,但3没有超时。返回3然后直接返回0。此情况与另一个答案相同-返回控制台,但3没有超时。返回3然后直接返回0nd谢谢!我知道我做错了。这正是我所需要的。注意,我使用的是
setEventIndex
的函数版本,因此我不必将
eventIndex
作为依赖项传递进来(这样,在装载时或者如果eventDate数组长度发生变化,效果就会被调用)万分感谢!我知道我做错了。这正是我所需要的。请注意,我使用的是
setEventIndex
的函数版本,因此我不必将
eventIndex
作为依赖项传递进来(这样,在装载时或如果eventDate数组长度发生变化,效果将被调用)