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

React开发TODO列表报appendChild is not a function错误

报错直接原因

你代码里的两个低级错误直接触发了appendChild is not a function:

  • const list = List.document.getElementsByClassName('.div-list')写法完全错误:List是你自定义的React函数组件,不是浏览器提供的DOM/全局对象,本身不存在document属性,这行代码的返回值是undefined,对undefined调用appendChild方法自然会抛出函数不存在的错误。
  • 就算你把这行改成document.getElementsByClassName('.div-list')也选不到元素:getElementsByClassName的参数只需要传纯类名字符串,不需要带类选择器前缀.,带.的写法是querySelector/querySelectorAll的语法,这里传参不对会拿到空的元素集合,对集合调用appendChild也会报错。
根本逻辑问题

你在用原生JavaScript命令式操作DOM的思路写React,这是框架使用方式的根本错误:
React是声明式框架,所有界面渲染由数据状态驱动,你不需要手动创建DOM节点、追加节点,只需要维护好对应的数据,React会自动根据数据变化更新真实DOM。你手动操作DOM的写法不仅容易出错,后续React触发组件重渲染时,你手动追加的节点还会被虚拟DOM的对比逻辑直接覆盖删除。

正确实现代码

按照React状态驱动的思路改写即可,不需要任何原生DOM操作:

  1. 父组件(存放表单和状态)
import { useState } from 'react'
import { List } from './List'

export default function TodoApp() {
  // 存储三个输入框的绑定值
  const [datos, setDatos] = useState({
    text: '',
    amount: '',
    date: ''
  })
  // 存储所有待办列表项
  const [todoItems, setTodoItems] = useState([])

  // 同步输入框值到状态
  const handleInputChange = (e) => {
    setDatos({
      ...datos,
      [e.target.name]: e.target.value
    })
  }

  // 表单提交逻辑,对应原cargarDatos方法
  const cargarDatos = (pool) => {
    pool.preventDefault()
    // 直接更新列表状态即可,不需要操作DOM
    const newItem = `${datos.text} ${datos.amount} ${datos.date}`
    setTodoItems([...todoItems, newItem])
    // 提交后清空输入框
    setDatos({ text: '', amount: '', date: '' })
  }

  return (
    <div>
      <form onSubmit={cargarDatos}>
        <input 
          name="text" 
          value={datos.text} 
          onChange={handleInputChange} 
          placeholder="待办内容"
        />
        <input 
          name="amount" 
          value={datos.amount} 
          onChange={handleInputChange} 
          placeholder="数量"
        />
        <input 
          name="date" 
          value={datos.date} 
          onChange={handleInputChange} 
          placeholder="日期"
        />
        <button type="submit">添加待办</button>
      </form>
      {/* 把列表数据传给List组件渲染 */}
      <List items={todoItems} />
    </div>
  )
}
  1. 改写后的List组件
import React from "react";

export function List ({ items }) {
  return (
    <>
      <h2>List</h2>
      <div className={'div-list'}>
        {/* 遍历传入的列表数据,自动渲染对应节点 */}
        {items.map((item, idx) => (
          <div className="item-List" key={idx}>
            {item}
          </div>
        ))}
      </div>
    </>
  )
}

新手写React牢记一个原则:只要你写的代码里出现了document.createElement、appendChild、getElementById/ClassName这类直接操作真实DOM的代码,99%的概率是写法错了,优先考虑用状态+JSX遍历的方式实现需求。

内容的提问来源于stack exchange,提问作者exodus

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 08:09:25