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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 00:32:07