Next.js中使用react-input-date-mask出现window错误的原因
Next.js中使用react-input-date-mask出现window错误的原因及解决办法
问题场景
在Next.js项目中使用react-input-date-mask组件实现日期输入掩码,代码结构与参考示例相似,但运行时出现window相关错误。代码如下:
import React from 'react' import ReactInputDateMask from 'react-input-date-mask'; export default function PartnersDetailsForm() { const [feildsValue, setFeildsValue] = useState({ name: "", lastName: "", birthDate: "", }) }); const onChangeHandler = (e) => { let changedValue; if (e.target.name === "CPF" || e.target.name === "birthDate" || e.target.name === "cell") { changedValue = e.target.value.replace(/\D+/g, ''); } else { changedValue = e.target.value; } setFeildsValue({ ...feildsValue, [e.target.name]: changedValue }); } return ( <> <ReactInputDateMask mask='DD/MM/YYYY' showMaskOnFocus={true} value={feildsValue.birthDate} onChange={(e) => {onChangeHandler(e)}} showMaskOnHover={true} /> </> )
错误原因
react-input-date-mask组件内部直接依赖浏览器环境的window对象,但Next.js默认采用服务端渲染(SSR)模式,在服务端渲染阶段window对象尚未存在,因此会触发"window is not defined"类错误。
解决办法
1. 动态导入组件并禁用SSR
使用Next.js的dynamic方法导入组件,明确设置ssr: false,让组件仅在客户端环境渲染:
import React, { useState } from 'react'; import dynamic from 'next/dynamic'; // 动态导入,禁用服务端渲染 const ReactInputDateMask = dynamic(() => import('react-input-date-mask'), { ssr: false }); export default function PartnersDetailsForm() { const [feildsValue, setFeildsValue] = useState({ name: "", lastName: "", birthDate: "", }); const onChangeHandler = (e) => { let changedValue; if (e.target.name === "CPF" || e.target.name === "birthDate" || e.target.name === "cell") { changedValue = e.target.value.replace(/\D+/g, ''); } else { changedValue = e.target.value; } setFeildsValue({ ...feildsValue, [e.target.name]: changedValue }); }; return ( <> <ReactInputDateMask mask='DD/MM/YYYY' showMaskOnFocus={true} value={feildsValue.birthDate} onChange={onChangeHandler} showMaskOnHover={true} /> </> ); }
2. 条件渲染组件(确保仅在客户端渲染)
通过useEffect标记客户端环境,仅当客户端就绪后再渲染组件:
import React, { useState, useEffect } from 'react'; import ReactInputDateMask from 'react-input-date-mask'; export default function PartnersDetailsForm() { const [feildsValue, setFeildsValue] = useState({ name: "", lastName: "", birthDate: "", }); const [isClient, setIsClient] = useState(false); // 组件挂载后标记为客户端环境 useEffect(() => { setIsClient(true); }, []); const onChangeHandler = (e) => { let changedValue; if (e.target.name === "CPF" || e.target.name === "birthDate" || e.target.name === "cell") { changedValue = e.target.value.replace(/\D+/g, ''); } else { changedValue = e.target.value; } setFeildsValue({ ...feildsValue, [e.target.name]: changedValue }); }; return ( <> {/* 仅在客户端环境渲染组件 */} {isClient && ( <ReactInputDateMask mask='DD/MM/YYYY' showMaskOnFocus={true} value={feildsValue.birthDate} onChange={onChangeHandler} showMaskOnHover={true} /> )} </> ); }
额外代码修正
原代码存在两处语法问题需同步修正:
- 缺少
useState导入,需改为import React, { useState } from 'react'; - 函数内部多了一个多余的
});,需删除该错误代码。
内容的提问来源于stack exchange,提问作者HamzaKhalid273
相关产品推荐
相关产品推荐

