React使用useReducer报trim读取undefined的TypeError错误
问题根因
首次渲染即触发Cannot read properties of undefined (reading 'trim')报错,是两个写法错误共同导致的:
useReducer初始值传参错误:调用useReducer时你直接把intialInputState函数作为第二个参数传入,没有执行该函数拿到初始状态对象。useReducer只有在传入第三个初始化函数参数时,才会执行函数生成初始state;只传两个参数时,第二个参数会被直接作为初始state。因此首次渲染时inputState是intialInputState函数本身,不存在value属性,inputState.value为undefined,传入校验函数执行value.trim()时就会触发报错,和报错栈指向表单文件校验逻辑位置完全吻合。- reducer兜底逻辑错误:当前reducer匹配不到对应action类型时,会直接返回
inputStateReducer函数本身作为state,后续如果触发未知type的dispatch,会再次把state替换为函数,触发同类报错。
修复步骤
- 修正useReducer初始值传参,两种写法二选一即可:
- 直接传入执行后的初始对象(适合当前简单场景):
// 原代码:const[inputState,dispatch] =useReducer(inputStateReducer,intialInputState); const [inputState, dispatch] = useReducer(inputStateReducer, intialInputState());- 使用useReducer懒初始化语法(适合初始状态计算逻辑复杂的场景):
const [inputState, dispatch] = useReducer(inputStateReducer, null, intialInputState); - 修正reducer兜底返回值,把reducer最后一行错误的返回值改为返回当前state:
const inputStateReducer=(state,action)=>{ if(action.type==='INPUT'){ return{value:action.value,isTouched:state.isTouched} } if(action.type==='BLUR'){ return{isTouched:true,value:state.value} } if(action.type==='RESET'){ return{value:'',isTouched:false} } // 删除原代码 return inputStateReducer; 替换为: return state; } - (可选边界加固) 在校验函数中增加空值兜底,避免极端场景下value非字符串类型触发报错:
// 姓名校验 UseInput((value) => (value ?? '').trim() !== ""); // 邮箱校验 const isEmail = (value) => (value ?? '').includes("@");
修改完成后刷新页面,首次渲染报错就会消失,表单输入、失焦、重置、提交逻辑都可以正常运行。
内容的提问来源于stack exchange,提问作者Rachna Singh Thakur
相关产品推荐
相关产品推荐

