Reputation: 177
What is wrong with this case. I want to display a random name and change it for every 2 seconds but after few seconds is changing continuously and look like the names are overwriting even when I clean the setName?
import React, {useState} from "react";
import "./styles.css";
export default function App() {
const [name, setName] = useState();
const arrayName = ['Tom','Alice','Matt','Chris'];
const nameChange = () => {
const rand = Math.floor(Math.random()*arrayName.length);
setName(arrayName[rand])
}
setInterval(()=>{
setName('');
nameChange();
console.log(name);
}, 2000)
return (
<div className="App">
<h1>Hello {name}</h1>
</div>
);
}
Upvotes: 1
Views: 1151
Reputation: 915
The issue is that you never do clearInterval
. Whenever the component calls render
, a new interval will issue.
Wrap setInterval
in useEffect
, which gets called when a component renders. The return of useEffect
is a function that dictates what happens on component unmounting phase. See more here
useEffect(){
const tmp = setInterval(()=>{
setName('');
nameChange();
console.log(name);
}, 2000)
return () => { clearInterval(tmp); };
}
Upvotes: 2
Reputation: 3656
The issue is that every time your component is rendered, you are creating a new interval.
The solution is to wrap the setInterval call in useEffect, and then return a function to useEffect to clear the interval.
import React, { useState, useCallback, useEffect } from 'react';
import './styles.css';
const arrayName = ['Tom', 'Alice', 'Matt', 'Chris'];
export default function App() {
const [name, setName] = useState();
const nameChange = useCallback(() => {
const rand = Math.floor(Math.random() * arrayName.length);
setName(arrayName[rand]);
}, [setName]);
useEffect(() => {
const intervalId = setInterval(() => {
setName('');
nameChange();
}, 2000);
return () => clearInterval(intervalId);
}, [nameChange]);
return (
<div className="App">
<h1>Hello {name}</h1>
</div>
);
}
Upvotes: 1
Reputation:
It's creating a new interval every time your component renders, which causes it to render again and you end up with an infinite loop.
Try this:
import React, {useState, useEffect, useCallback} from "react";
import "./styles.css";
const arrayName = ['Tom','Alice','Matt','Chris'];
export default function App() {
const [name, setName] = useState();
const nameChange = useCallback(() => {
const rand = Math.floor(Math.random()*arrayName.length);
setName(arrayName[rand])
}, []);
useEffect(() => {
const interval = setInterval(() => {
setName('');
nameChange();
}, 2000)
return () => clearInterval(interval)
}, [nameChange]);
return (
<div className="App">
<h1>Hello {name}</h1>
</div>
);
}
Upvotes: 3