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

Footer组件中useEffect引发每4秒全页重渲染问题排查

问题分析与解决方案:Footer组件每4秒全页重渲染,关联CookieBanner组件

问题现象

Footer组件中,useEffect每4秒触发一次全页及组件重渲染,预期仅更新轮播的项目元素。注释掉<CookieBanner />组件后该现象消失,且数据的控制台日志每4秒输出一次。

核心问题原因

  1. CookieBanner是异步客户端组件:在Next.js的"use client"组件中,不能将组件定义为async函数。异步组件会返回Promise,React无法正确处理客户端组件的异步返回值,导致父组件(Footer)每次状态更新(比如currentProject变化)时,CookieBanner组件都会被重新初始化,进而触发不必要的全页重渲染。
  2. 内部组件重复创建:ButtonComponent定义在CookieBanner组件内部,每次组件渲染都会重新创建这个子组件,间接导致重渲染优化失效。

解决方案

1. 移除CookieBanner的async关键字

当前CookieBanner代码中没有异步操作,完全不需要使用async,改为普通函数组件即可修复核心重渲染问题。

2. 提取内部组件到外部

将ButtonComponent移到CookieBanner组件外部,避免每次渲染重复创建组件,进一步优化重渲染性能。

修改后的CookieBanner代码

"use client"

import Link from "next/link"
import CookieConsent from "react-cookie-consent"

type CookieBannerProps = {
  data?: CookieBanner
}

type CookieBannerButtonProps = {
  children: React.ReactNode
  onClick: () => void
  privacy_url?: string
  privacy_link_text?: string
}

// 提取到组件外部,避免每次渲染重新创建
const ButtonComponent = ({ children, onClick, privacy_url, privacy_link_text }: CookieBannerButtonProps) => {
  return (
    <div className="flex items-center gap-5">
      {privacy_url && (
        <Link
          href={`/${privacy_url}`}
          className="flex items-center gap-2 text-sm text-white lg:text-base"
        >
          {privacy_link_text ? privacy_link_text : "Privacy Policy"}
        </Link>
      )}
      <button
        onClick={onClick}
        className="inline-flex items-center text-sm text-white lg:text-base"
      >
        <span className="pl-3">{children}</span>
      </button>
    </div>
  )
}

export function CookieBanner({ data }: CookieBannerProps) {
  if (!data || !data.enabled) {
    return null
  }

  const { title, buttonText, privacy_link_text, privacy_url } = data
  const debug = process.env.NODE_ENV === "development"

  return (
    <CookieConsent
      disableStyles
      location="bottom"
      buttonText={buttonText ? buttonText : "Accepteren"}
      cookieName="CookieConsent"
      expires={365}
      debug={debug}
      containerClasses="bg-black text-white justify-between flex flex-col sm:flex-row px-6 py-4 w-full sm:items-center fixed gap-3 bottom-0 left-0 w-full z-40"
      ButtonComponent={(props) => (
        <ButtonComponent
          {...props}
          privacy_url={privacy_url}
          privacy_link_text={privacy_link_text}
        />
      )}
    >
      <h3 className="text-lg sm:text-xl">{title}</h3>
    </CookieConsent>
  )
}

额外优化建议

  • Footer中的Socials组件也可以提取到组件外部,或者用React.memo包裹,避免每次Footer渲染重复创建组件。
  • 确保footerData保持为常量(当前代码已满足),避免每次渲染重新创建对象。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 05:33:23