【问题标题】:Why is this part of my component rerending on interval call?为什么我的组件的这一部分会在内部调用时重新呈现?
【发布时间】:2020-05-06 17:59:33
【问题描述】:

我正在构建一个带有反应钩子的测验应用程序并且我遇到了一些问题。

我从 20 开始倒计时并设置了间隔,但这会导致我的组件中不相关的东西重新渲染。

当组件挂载时,我使用Effect 为每个头像附加一个分数。 allAvatars 是传入此组件的道具。

 const [userScores, setUserScores] = useState([])


 useEffect(() => {
   const userScoreObject = allAvatars.map((user) => {
   user.score = 0;
   return user;
 })
  setUserScores(userScoreObject);
 }, [])

然后,根据游戏的状态,我的计时器还有另一个 useEffect。

useEffect(() => { 
  let interval; 
  if (gameState === 'play') {
    interval = setInterval(() => {
      setTimer(timer -= 1)
  }, 1000)
 } else if (gameState === 'pause') {
  return clearInterval(interval);
 }
 return () => clearInterval(interval)
 }, [gameState])

我只将 gameState 放在依赖数组中,因为我只希望在游戏状态更改时调用此效果。游戏状态初始化为'play'

在我的 JSX Im 中映射这些用户分数。

 {
    userScores && 
      userScores.map((user, index) => {
        console.log(user)
        return (
          <div key={index} >
            <img src={user.avatar} alt='avatar'></img>
            <p>{user.score}</p>

          </div>
        )
      })
  }

问题是这个控制台日志每秒都在发生。为什么计时器会导致重新渲染?

谢谢

【问题讨论】:

  • setTimer是设置状态吗?更改状态会导致按设计重新渲染。
  • 但是重新渲染整个组件的行为是预期的吗?
  • 是的。当组件的状态发生变化时,React 总是会对其进行完整的重新渲染。虚拟 DOM 可能会最小化对 DOM 的实际更改,但渲染功能仍将运行。如果您不希望渲染功能运行,那么您可以将不想重新渲染的部分拆分为单独的组件并对其执行React.memo

标签: javascript reactjs react-hooks setinterval


【解决方案1】:

当组件的状态发生变化时,React 总是会对其进行完整的重新渲染。因此,setTimer 调用将导致您的渲染函数执行。请确保不要将 重新渲染DOM 更新 混淆。

由于虚拟 DOM 减少了对页面的更改,重新渲染通常是可以接受的性能影响,但有一些成本。如果正在进行一些昂贵的渲染,您可以考虑将不想重新渲染的部分拆分为自己的组件,并在其上使用React.memo,这样即使父组件重新渲染它也不会' t(前提是它的 props 不变)。

【讨论】:

    猜你喜欢
    • 2019-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-25
    • 2012-08-04
    • 1970-01-01
    相关资源
    最近更新 更多