Reputation: 427
Im building a quiz app with react hooks and im having some problems.
I have a countdown from 20 with set interval but this is causing something unrelated in my component to rerender.
When component mounts I useEffect to attach a score to each avatar. allAvatars is a prop that is passed in to this component.
const [userScores, setUserScores] = useState([])
useEffect(() => {
const userScoreObject = allAvatars.map((user) => {
user.score = 0;
return user;
})
setUserScores(userScoreObject);
}, [])
I then have another useEffect for my timer depending on the state of the game.
useEffect(() => {
let interval;
if (gameState === 'play') {
interval = setInterval(() => {
setTimer(timer -= 1)
}, 1000)
} else if (gameState === 'pause') {
return clearInterval(interval);
}
return () => clearInterval(interval)
}, [gameState])
Im only putting gameState in the dependency array as I only want this effect to be called when the gamestate changes. The game state is initialized as 'play'
In my JSX Im mapping these userscores.
{
userScores &&
userScores.map((user, index) => {
console.log(user)
return (
<div key={index} >
<img src={user.avatar} alt='avatar'></img>
<p>{user.score}</p>
</div>
)
})
}
The problem is that this console log is happening every second. Why is the timer causing this to rerender?
Thanks
Upvotes: 0
Views: 843
Reputation: 78890
React will always do a full rerender of a component when its state changes. Therefore, the setTimer
call will cause your render function to execute. Be sure you don't confuse a re-render with a DOM update.
Often times re-rendering is an acceptable performance impact because of the virtual DOM reducing changes to the page, but there is some cost. If there is some costly rendering going on, you could consider splitting out the part you don't want to re-render into its own component, and use React.memo
on it so that even if the parent component re-renders it won't (provided its props don't change).
Upvotes: 1