You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js 13中点击事件改状态触发无限循环,箭头函数无效

问题分析与解决方案

这不是Next.js 13特有的问题,核心是客户端组件误用async声明+useCallback依赖/闭包陷阱导致的异常渲染。

问题原因

  1. 客户端组件不能是async函数:Next.js 13中,标记'use client'的组件必须是同步函数,async组件仅用于服务器组件。你的代码里把客户端组件声明为async function Page(),这种混合写法会触发组件渲染逻辑异常,引发重复渲染。
  2. useCallback的闭包问题:你的useCallback依赖数组为空,回调函数捕获的是组件初始化时的vidModal状态。每次调用setVidModal时,都是基于初始状态更新,组件重新渲染后cb仍保留旧闭包,状态更新逻辑异常,进一步加剧渲染循环。

修复步骤

  1. 移除async声明:将客户端组件改为普通同步函数
'use client'
import { useState, useCallback } from 'react'

export default function Page() { // 去掉async关键字
  // initialize state
  const [vidModal, setVidModal] = useState({
    open: false,
    videoId: '',
    opts: {}
  })

  // 后续代码...
}
  1. 修正状态更新逻辑:二选一即可
    • 方案一:给useCallback添加正确依赖
      const cb = useCallback(() => {
        setVidModal({...vidModal, open: !vidModal.open});
      }, [vidModal]) // 加入vidModal作为依赖项
      
    • 方案二:使用函数式更新避免闭包陷阱(推荐)
      const cb = useCallback(() => {
        setVidModal(prevState => ({...prevState, open: !prevState.open}));
      }, []) // 依赖数组可保持为空
      

效果验证

修改后,点击img元素时vidModal状态会正确切换,控制台的console.log(vidModal)只会在状态真正变化时打印,不会出现无限循环打印的情况。

内容的提问来源于stack exchange,提问作者DatMomoAgain

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 13:42:39