Next.js中navigator未定义报错及表单提交API执行异常问题
问题解决指南
1. 修复navigator is not defined错误
这个错误是因为react-simplemde-editor依赖的Codemirror库在服务端渲染(SSR)时,尝试访问浏览器专属的navigator对象,但服务端环境不存在这个对象。
解决方法:用Next.js的动态导入功能,仅在客户端加载编辑器组件,禁用SSR:
// 替换原有的SimpleMDE导入语句 import dynamic from 'next/dynamic'; const SimpleMDE = dynamic(() => import('react-simplemde-editor'), { ssr: false, loading: () => <div>加载编辑器...</div> // 可选的加载提示 });
同时把样式导入放到useEffect中,确保只在客户端执行:
import { useEffect } from 'react'; // 在组件内部添加 useEffect(() => { import('easymde/dist/easymde.min.css'); }, []);
2. 解决表单提交后重定向未进入catch、后端API未执行的问题
先修复上述SSR错误,再排查以下几点:
- 验证API路由配置:确认
/issues/new对应的后端路由存在,请求方法为POST,且能正确接收title和description参数。 - 增强错误日志:修改catch块,打印更详细的错误信息,方便定位问题:
catch (error) { if (axios.isAxiosError(error)) { console.log('API请求错误:', error.response?.data || error.message); } else { console.log('其他错误:', error); } // 临时注释重定向,先查看错误日志再恢复 // router.push("/issues"); } - 完善表单提交逻辑:给Button添加
type="submit"属性,确保触发正确的表单提交事件;同时确认await axios.post正确等待请求完成,避免未完成请求就重定向导致请求被取消。
修改后的完整组件代码:
"use client"; import { Button, TextField } from "@radix-ui/themes"; import dynamic from 'next/dynamic'; import { useEffect } from 'react'; import { useForm, Controller } from "react-hook-form"; import axios from "axios"; import { useRouter } from "next/navigation"; const SimpleMDE = dynamic(() => import('react-simplemde-editor'), { ssr: false, loading: () => <div>加载编辑器...</div> }); interface IssueInterface { title: string; description: string; } const NewIssue = () => { const router = useRouter(); const { register, control, handleSubmit } = useForm<IssueInterface>(); useEffect(() => { import('easymde/dist/easymde.min.css'); }, []); return ( <form className="max-w-xl space-y-3" onSubmit={handleSubmit(async (data) => { try { await axios.post("/issues/new", data); router.push("/issues"); } catch (error) { if (axios.isAxiosError(error)) { console.log('API请求错误:', error.response?.data || error.message); } else { console.log('其他错误:', error); } } })} > <TextField.Root> <TextField.Input placeholder="Title" {...register("title")} /> </TextField.Root> <Controller name="description" control={control} render={({ field }) => ( <SimpleMDE placeholder="Description" {...field} /> )} /> <Button type="submit">Create Issue</Button> </form> ); }; export default NewIssue;
内容的提问来源于stack exchange,提问作者KRUSHANU MOHAPATRA
相关产品推荐
相关产品推荐

