user10045300
user10045300

Reputation: 427

Why is this part of my component rerending on interval call?

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

Answers (1)

Jacob
Jacob

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

Related Questions