[英]Javascript - How to loop through an array over and over again in React
想象一下,我有一個這樣的對象數組:
const items = [
{name: "item 0"},
{name: "item 1"},
{name: "item 2"}
]
像這樣的組件:
const [currentItemIndex, setCurrentItemIndex] = useState(0)
setInterval(function () {
if (currentItemIndex < 3) {
setCurrentItemIndex(currentItemIndex + 1);
} else {
clearInterval();
}
}, 5000);
return (
<div>
<p> {items[currentItemIndex].name} <p>
</div>
)
我想每 5 秒更新一次currentItemIndex
以便div
顯示下一個項目,如果它到達末尾,它應該重新開始: 0, 1, 2, 0, 1, 2, 0, 1, 2...
。
問題是:它第一次正確循環,但在到達結尾后,它顯示第一個項目的幾分之一秒,然后轉到最后一個項目: 0, 1, 2, 0 (really quick to) 2
。
我做錯了什么?
我搜索了這個,但每篇文章都在談論“如何防止無限循環”,而不是“如何使用它們”!
您可以使用useEffect
和setTimeout
來做到這一點,如下所示:
const items = [{ name: "item 0" }, { name: "item 1" }, { name: "item 2" }]; const App = () => { const [currentItemIndex, setCurrentItemIndex] = React.useState(0); React.useEffect(() => { setTimeout( () => setCurrentItemIndex((currentItemIndex + 1) % items.length), 1000 ); }, [currentItemIndex]); return ( <div> <p> {items[currentItemIndex].name} </p> </div> ); }; // export default App; ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script> <div id="root"></div>
我發現您創建的這種邏輯存在一些問題。
首先,需要為clearInterval
提供一個您在創建setInterval
function 時創建的變量(如您在此處看到的),所以這個clearInterval()
什么都不做。
除此之外,您不想在currentItemIndex
達到其閾值時清除計時器,而是希望它 go 回到零。
在 React 中,我們通常使用useEffect
來計時事件,因為您需要在卸載時清除它們,這樣您就不會在組件卸載后繼續運行它們。 像這樣的東西:
useEffect(() => {
const timer = setInterval(yourFunction);
return () => clearInterval(timer);
}, [])
如果您願意,可以使用這種方法。 您創建一個 function 使用它將在 5 秒后使用超時設置 state。 設置 state 后,您再次調用相同的方法。 為了做出反應,您使用 useEffect 調用此方法一次。
import { useEffect, useState } from "react";
const items = [{ name: "item 0" }, { name: "item 1" }, { name: "item 2" }];
export default function App() {
const [currentItemIndex, setCurrentItemIndex] = useState(0);
useEffect(() => {
incrementAfterDelay(1000, 1, 2);
}, []);
const incrementAfterDelay = (delay, step, lastStep) => {
setTimeout(
() =>
setCurrentItemIndex((value) => {
return (value < lastStep)? value + step : 0
}, incrementAfterDelay(delay, step, lastStep)),
delay
);
};
return (
<div>
<p> {items[currentItemIndex].name} </p>
</div>
);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.