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

咨询:Next.js/Script加载CMS动态365表单,页面返回后无法渲染的解决办法

解决Next.js导航返回后动态365表单不渲染的问题

方案1:结合路由监听重新触发表单初始化

Next.js客户端导航时,Script组件不会自动重新执行缓存的脚本,可通过监听路由变化,在回到目标页面时手动触发表单初始化逻辑:

import { useRouter } from 'next/router';
import Script from 'next/script';
import { useEffect, useState } from 'react';

export default function FormPage() {
  const router = useRouter();
  const [shouldInitForm, setShouldInitForm] = useState(true);

  const init365Form = () => {
    // 替换为365表单的实际初始化函数,比如调用其全局初始化方法
    if (window.initMicrosoftForm) {
      window.initMicrosoftForm('#form-container');
    }
  };

  useEffect(() => {
    const handleRouteChange = (url) => {
      // 根据实际路由调整判断条件
      if (url === '/form-page') {
        setShouldInitForm(true);
      }
    };

    router.events.on('routeChangeComplete', handleRouteChange);
    return () => {
      router.events.off('routeChangeComplete', handleRouteChange);
    };
  }, [router]);

  useEffect(() => {
    if (shouldInitForm) {
      init365Form();
      setShouldInitForm(false);
    }
  }, [shouldInitForm]);

  return (
    <>
      <div id="form-container"></div>
      <Script
        src="https://your-cms-form-script-url.js"
        strategy="afterInteractive"
        onLoad={init365Form}
      />
    </>
  );
}

方案2:手动注入/移除脚本避免缓存

绕过Next.js Script组件的缓存机制,在组件挂载时手动创建脚本标签,卸载时移除,确保每次进入页面都重新加载脚本:

import { useEffect } from 'react';

export default function FormPage() {
  const init365Form = () => {
    if (window.initMicrosoftForm) {
      window.initMicrosoftForm('#form-container');
    }
  };

  useEffect(() => {
    const script = document.createElement('script');
    script.src = 'https://your-cms-form-script-url.js';
    script.async = true;
    script.onload = init365Form;

    document.body.appendChild(script);

    return () => {
      // 卸载时清理脚本和全局变量
      document.body.removeChild(script);
      delete window.initMicrosoftForm;
    };
  }, []);

  return <div id="form-container"></div>;
}

方案3:通过key强制重置表单容器

给表单容器添加基于路由状态的key,让React在页面返回时重新渲染容器,确保脚本执行时能找到全新的DOM节点:

import { useRouter } from 'next/router';
import Script from 'next/script';
import { useEffect } from 'react';

export default function FormPage() {
  const router = useRouter();
  // 用asPath作为key,路由变化后容器自动重新渲染
  const containerKey = router.asPath;

  const init365Form = () => {
    if (window.initMicrosoftForm) {
      window.initMicrosoftForm('#form-container');
    }
  };

  useEffect(() => {
    // 延迟执行确保DOM已就绪
    const timer = setTimeout(init365Form, 100);
    return () => clearTimeout(timer);
  }, [containerKey]);

  return (
    <>
      <div id="form-container" key={containerKey}></div>
      <Script
        src="https://your-cms-form-script-url.js"
        strategy="lazyOnload"
      />
    </>
  );
}

方案4:App Router下的客户端组件处理(Next.js 13+)

如果使用App Router,将表单组件标记为客户端组件,结合路由监听处理:

'use client';

import { usePathname } from 'next/navigation';
import Script from 'next/script';
import { useEffect, useState } from 'react';

export default function FormPage() {
  const pathname = usePathname();
  const [shouldInit, setShouldInit] = useState(true);

  const initForm = () => {
    if (window.initMicrosoftForm) {
      window.initMicrosoftForm('#form-container');
    }
  };

  useEffect(() => {
    if (pathname === '/form-page') {
      setShouldInit(true);
    }
  }, [pathname]);

  useEffect(() => {
    if (shouldInit) {
      initForm();
      setShouldInit(false);
    }
  }, [shouldInit]);

  return (
    <>
      <div id="form-container"></div>
      <Script src="https://your-cms-form-script-url.js" onLoad={initForm} />
    </>
  );
}

核心思路都是确保每次回到页面时,脚本要么重新加载,要么初始化逻辑被重新调用,同时保证表单容器是脚本可识别的有效DOM节点。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 03:16:05