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

Preact函数组件清空todo数组后DOM残留元素问题求助

问题根因

你的CLEAR按钮放置在form表单内部,且未显式指定type属性,浏览器会默认将form内未声明type的按钮识别为submit类型。点击CLEAR按钮时会依次触发两个事件:

  • 首先触发按钮的onClick事件,执行deleteList将todos数组重置为空
  • 接着触发form的submit提交事件,执行onSubmit逻辑,此时input值为空字符串,会往todos数组中追加一个空字符串元素

空字符串在渲染时不会显示文本内容,所以最终页面上只会残留一个DEL按钮,和你遇到的现象完全一致。

修复方案

给CLEAR按钮显式添加type="button"属性,声明为普通按钮,不会触发表单提交即可。

修正后的核心代码片段:

<button type="button" onClick={deleteList}>CLEAR</button>

完整修正后的组件代码:

import { useState } from 'preact/hooks';

const Todo = () => {
  const [input, setInput] = useState('')
  const [todos, setTodos] = useState([])

  const onInput = ev => {
    setInput(ev.target.value)
  }

  const deleteItem = itm => {
    setTodos(todos.filter(el => el != itm))
  }

  const deleteList = () => {
    setTodos([])
  }

  const onSubmit = ev => {
    ev.preventDefault()
    setTodos([...todos, input])
    setInput('')
  }

  return (
    <>
      <form onSubmit={onSubmit}>
        <input
          type="text"
          onInput={onInput}
          value={input}
          placeholder="Todo..."
          autoFocus="autofocus"
        />
        <button type="submit">Eingabe</button>
        {/* 新增type="button"属性 */}
        <button type="button" onClick={deleteList}>CLEAR</button>
      </form>
      <ul>
        { todos.map(el => {
          return (
              <li key={el}>
                {el}
                <button onClick={() => deleteItem(el)}>DEL</button>
              </li>
          )
        }) }
      </ul>
    </>
  )
}

export default Todo

额外补充:你当前map渲染li时没有加key属性,属于React/Preact的规范警告项,上面的代码里也同步给li加了key属性,避免后续出现其他渲染异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 06:24:03