React TodoApp提交表单报错:Cannot read properties of undefined (reading 'length')
问题
点击「Agregar」按钮时希望控制台打印新的todo,但出现以下错误:Uncaught TypeError: Cannot read properties of undefined (reading 'length')
相关代码如下:
TodoApp.jsx
import { useReducer } from "react" import { todoReducer } from "./todoReducer"; import { TodoList } from "./TodoList"; import { TodoAdd } from "./TodoAdd"; export const TodoApp = () => { const initialState = [ { id: new Date().getTime(), description: "recolectar piedra de alma", done: false, }, { id: new Date().getTime() * 3, description: "recolectar piedra de infinito", done: false, }, ]; const [todos, dispatchTodo] = useReducer(todoReducer, initialState); const handleNewTodo = (todo) => { console.log({todo}); }; return ( <> <h1> TodoApp (10) <small>Pendientes 2</small> </h1> <hr /> <div className="row"> <div className="col-7"> <TodoList todos={todos} /> </div> </div> <div className="col-5"> <h4>Agregar TODO</h4> <hr /> <TodoAdd onNewTodo={handleNewTodo} /> </div> </> ); };
TodoAdd.jsx
import { useForm } from '../hooks/useForm'; export const TodoAdd = ({ onNewTodo }) => { const { description, onInputChange, onResetForm } = useForm({ description: '' }); const onFormSubmit = ( event ) => { event.preventDefault(); if ( description.length <= 1 ) return; const newTodo = { id: new Date().getTime(), done: false, description: description, } onNewTodo(newTodo); onResetForm(); } return ( <form onSubmit={ onFormSubmit }> <input type="text" placeholder="¿Qué hay que hacer?" className="form-control" name="description" value={ description } onChange={ onInputChange } /> <button type="submit" className="btn btn-outline-primary mt-1" > Agregar </button> </form> ) }
推测description未正确传递到表单中,调用length时无法获取数值导致验证失败,但不知道如何处理。
解决方案
错误核心是description变量为undefined,读取length属性时触发报错。问题大概率出在你自定义的useForm钩子实现上——如果钩子没有正确初始化或返回对应的值,就会出现这种情况。
方案1:修复useForm钩子
确保useForm能正确返回初始的description值及对应方法,标准实现参考如下:
// hooks/useForm.js import { useState } from 'react'; export const useForm = (initialForm = {}) => { const [formState, setFormState] = useState(initialForm); const onInputChange = ({ target }) => { const { name, value } = target; setFormState({ ...formState, [name]: value }); }; const onResetForm = () => { setFormState(initialForm); }; // 展开formState属性,确保description能被正确解构 return { ...formState, onInputChange, onResetForm }; };
方案2:添加兜底判断
如果暂时不想修改useForm,可以在使用description时先做兜底处理,避免undefined报错:
// 修改TodoAdd.jsx中的onFormSubmit方法 const onFormSubmit = ( event ) => { event.preventDefault(); // 先判断description是否存在,再检查长度 if ( !description || description.length <= 1 ) return; const newTodo = { id: new Date().getTime(), done: false, description: description || '', } onNewTodo(newTodo); onResetForm(); }
同时给input的value属性也加上兜底:
<input type="text" placeholder="¿Qué hay que hacer?" className="form-control" name="description" value={ description || '' } onChange={ onInputChange } />
额外检查
确认TodoAdd组件中useForm的导入路径正确,确保从../hooks/useForm能找到对应文件,避免因导入错误导致钩子未正确加载。
内容的提问来源于stack exchange,提问作者Gaxt Zerpa
相关产品推荐
相关产品推荐

