So I basically want a tag that looks like this.
This is <a href="https://nextjs.org">tyty<span> {textArray[Index]}</span></a>
and I want textArray[Index] to show a different value every 3 seconds. Currently my code cycles through the array, however, it seems to gofrom Array 0 to Array 2 then Array 4.
I want it to Show array 0 then 3 seconds later array 1, 3 secs, array 2, 3 secs, array 3, then back to array 0 and repeat.
My code looks like this:
const textArray = [
"digital",
"development",
"graphics",
"blog"
]
const [Index, setIndex] = useState(0);
const intervalID = setTimeout(changeText, 3000);
function changeText(){
if(Index >= 0 && Index < 4) {
setIndex((prevIndex) => prevIndex);
}
if(Index > 3){
setIndex((prevIndex) => prevIndex=0);
}
}
Why can't I also seem to get it to go through array 1 and array 3.
When I go to google dev mode, I type in Index into the console and it says its not defined. Same with textArray.
CodePudding user response:
First - memoize your array or other objects using useState or useMemo. Without that - objects and arrays will be recreated on each render. And if for primitives like boolean, numbers, strings it is - ok and depsArray
s of useMemo and useEffect will handle them right - for arrays and object it will not be ok due to even if object is the same in terms of values - reference to this object will be changed (new object created) and that will cause pretty bad behavior and tons of unneded re-renders, especially if you pass those objects and arrays down to the child components.
Next - it is setInterval, not setTimeout.
Last - always clear Intervals you created.
import { useState, useEffect, useMemo } from "react";
export default function App() {
// memoize the array and dont recreate it on each render
const textArray = useMemo(
() => ["digital", "development", "graphics", "blog"],
[]
);
const [index, setIndex] = useState(0);
// Will be recalculated when index or textArray changed
const text = useMemo(() => {
return textArray[index];
}, [index, textArray]);
useEffect(() => {
// setInterval, not the setTimeout
const intervalId = setInterval(() => {
// Index will go up but % will cut it down
setIndex((prev) => (prev 1) % textArray.length);
}, 3000);
return () => clearInterval(intervalId);
}, [textArray]);
return (
<div className="App">
This is{" "}
<a href="https://nextjs.org">
tyty<span> {text}</span>
</a>
</div>
);
}