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

NextJS 13.4客户端组件在Playwright测试中表单异常提交问题

解决Next.js 13.4 App Router中表单意外提交导致Playwright测试失败的问题

问题分析

点击type="button"的按钮本不应触发表单默认提交,但测试中出现页面刷新,大概率是以下几个原因:

  • 客户端组件未正确标记'use client',导致React hooks失效、事件处理逻辑未执行
  • 表单元素存在属性错误,干扰了表单行为
  • Playwright测试未等待组件完成hydration,操作时机过早

具体修复步骤

1. 确保所有客户端组件添加'use client'指令

在Next.js 13.4 App Router中,使用useState、自定义hooks(如useModal)的组件必须显式声明为客户端组件,否则会被当作服务器组件执行,导致hooks报错、事件逻辑失效。

在InitialForm.jsx、Modal.jsx、SignUpForm.jsx的顶部添加:

'use client';

// 后续导入和组件代码

2. 修正表单元素的属性错误

你的InitialForm中第二个输入框的name属性写错为"name",这会导致表单数据异常,甚至干扰默认行为,修正为:

<input name="name" onChange={(e) => setName(e.target.value)} />
<input name="email" onChange={(e) => setEmail(e.target.value)} />

3. 简化按钮事件逻辑,移除多余的preventDefault

type="button"的按钮默认不会触发表单提交,因此无需在onClick中调用event.preventDefault(),直接调用toggle即可:

<button
  type="button"
  data-testid="open-signup-modal-button"
  onClick={toggle}
>
  Continue
</button>

同时可以移除<form>上的onSubmit处理,因为没有触发提交的场景。

4. 验证useModal的正确性

确保自定义useModal hook正确切换状态:

'use client';
import { useState } from 'react';

export function useModal() {
  const [isVisible, setIsVisible] = useState(false);
  const toggle = () => setIsVisible(prev => !prev);
  return [isVisible, toggle];
}

5. 优化Playwright测试,适配Next.js Hydration

Next.js的App Router在页面加载时会进行hydration,过早操作元素可能导致逻辑未生效。修改测试代码,等待元素可交互后再操作:

test('should display SignUpForm on button clicked', async ({ page }) => {
  await page.goto('/');
  // 等待按钮完全加载并可交互
  await page.getByTestId('open-signup-modal-button').waitFor({ state: 'enabled' });
  await page.getByTestId('open-signup-modal-button').click();
  // 延长超时时间,确保模态框有足够时间渲染
  await expect(page.getByTestId('modal-signup')).toBeVisible({ timeout: 5000 });
});

同时确保Modal组件的根元素添加了data-testid="modal-signup":

export default function Modal({ isVisible, hide, children }) {
  if (!isVisible) return null;
  return (
    <div data-testid="modal-signup" className="modal-container">
      {children}
      <button onClick={hide}>Close</button>
    </div>
  );
}

验证修复

完成上述修改后,重新运行Playwright测试,此时点击按钮会正确触发模态框显示,不会触发表单刷新。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 14:22:12