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

Next.js中如何用useEffect Hook仅渲染一次Google翻译组件

解决Google翻译按钮重复渲染问题

问题场景

仅在单个页面中使用以下Google翻译组件,却出现两个独立的翻译按钮实例:

import { useEffect } from "react";

const GoogleTranslate = () => {
  useEffect(() => {
    let addScript = document.createElement("script");
    addScript.setAttribute(
      "src",
      "//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"
    );

    document.body.appendChild(addScript);

    window.googleTranslateElementInit = googleTranslateElementInit;
  }, []);

  const googleTranslateElementInit = () => {
    return new window.google.translate.TranslateElement(
      {
        pageLanguage: "en",
        layout: google.translate.TranslateElement.InlineLayout.BUTTON,
      },
      "google_translate_element"
    );
  };
  return <div id="google_translate_element"></div>;
};

export default GoogleTranslate;

问题原因

  1. 组件可能被重复挂载(比如路由切换时未正确卸载、父组件重复渲染导致该组件多次实例化)
  2. 每次组件挂载都会向页面添加Google翻译脚本,脚本加载完成后触发googleTranslateElementInit,若全局函数被多次赋值,会重复创建翻译实例
  3. Google翻译脚本本身的缓存机制,会导致重复添加脚本时初始化逻辑多次执行

解决方法

通过添加判断逻辑,避免重复添加脚本和创建翻译实例,同时处理组件卸载时的副作用:

import { useEffect } from "react";

const GoogleTranslate = () => {
  useEffect(() => {
    // 前置检查:避免重复初始化
    const hasTranslateScript = document.querySelector('script[src*="translate.google.com/translate_a/element.js"]');
    const hasTranslateInstance = document.querySelector('#google_translate_element iframe');
    
    if (hasTranslateScript || hasTranslateInstance) return;

    // 创建并添加翻译脚本
    const addScript = document.createElement("script");
    addScript.setAttribute(
      "src",
      "//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"
    );
    document.body.appendChild(addScript);

    // 定义全局初始化函数,完成后清理
    window.googleTranslateElementInit = () => {
      new window.google.translate.TranslateElement(
        {
          pageLanguage: "en",
          layout: window.google.translate.TranslateElement.InlineLayout.BUTTON,
        },
        "google_translate_element"
      );
      delete window.googleTranslateElementInit;
    };

    // 组件卸载时清理资源
    return () => {
      if (addScript && addScript.parentNode) addScript.parentNode.removeChild(addScript);
      if (window.googleTranslateElementInit) delete window.googleTranslateElementInit;
      const translateContainer = document.getElementById('google_translate_element');
      if (translateContainer) translateContainer.innerHTML = '';
    };
  }, []);

  return <div id="google_translate_element"></div>;
};

export default GoogleTranslate;

关键修改点说明

  • 前置检查:先判断页面是否已有翻译脚本或实例,存在则直接返回,避免重复执行初始化逻辑
  • 清理全局函数:初始化完成后删除window.googleTranslateElementInit,防止后续脚本加载时重复触发
  • 卸载清理:组件卸载时移除脚本、删除全局函数、清空翻译容器,避免残留实例影响其他页面

内容的提问来源于stack exchange,提问作者Musiur Alam Opu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 08:25:40