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

React TodoList初始化出现空条目问题及解决咨询

问题

刷新或首次打开React TodoList应用时,列表里会出现一个名称为空的条目,还带着操作按钮;就算用&&判断列表长度,这个空条目也消不掉,打印todos发现数组里本来就有1个空对象。

问题截图:
空条目截图

相关代码:

const App = () => {
  const [todos, setTodos] = useState([{
    userInput: null,
    isDone: false,
  }])
  
  const addItem = (userInput) => {
    const newTodos = [...todos, {userInput}]
    setTodos(newTodos)
  }
  const markItem = index =>{
    const newTodos = [...todos];
    newTodos[index].isDone = true;
    setTodos(newTodos);
  }

  const removeItem = index => {
    const newTodos = [...todos];
    newTodos.splice(index,1);
    setTodos(newTodos);
  }


  return (
    <div className>
      <Calender />
      <TodoInput addItem={addItem} />
      {(todos?.length > 0 )  && <TodoList todos={todos} removeItem={removeItem} markItem={markItem} />}
    </div>
  );
}

export default App;



const TodoList = ({ todos,removeItem,markItem }) => {
  
  return (
    <div>
      <ul>
        {todos?.map((todo,index) => {
          return (
           <li key={index} >
             <TodoItem todo={todo} index={index} removeItem={removeItem} markItem={markItem} />
          </li>
          )
        })}
      </ul>

    </div>
  )
}



const TodoItem = ({todo,index,removeItem,markItem}) => {
  return (
    <div>
        <span className={(todo.isDone ? "line-through" : "")}>{todo.userInput}</span>
        <div>
            <button onClick={()=>markItem(index)}>✔</button> 
            <button onClick={()=>removeItem(index)}>X</button>
        </div>
    </div>
  )
}

export default TodoItem
解决方案

1. 修正初始化状态

问题核心是你给todos的初始状态里直接塞了一个userInput: null的空条目,页面一加载自然会渲染它。把初始数组改成空的就行:

// App组件里的useState修改为
const [todos, setTodos] = useState([])

2. 补全添加条目的字段(避免结构不一致)

现在addItem里只传了userInput,没加isDone字段,虽然不影响渲染,但会导致数组里的对象结构不一。建议补充完整:

const addItem = (userInput) => {
  const newTodos = [...todos, { userInput, isDone: false }]
  setTodos(newTodos)
}

3. 过滤空输入(可选优化)

为了防止用户添加空内容的条目,可以在addItem里加个判断,空输入直接不处理:

const addItem = (userInput) => {
  // 过滤掉纯空格的输入
  if (!userInput.trim()) return;
  const newTodos = [...todos, { userInput, isDone: false }]
  setTodos(newTodos)
}

4. 渲染时过滤无效条目(兜底)

如果担心还有其他情况产生空条目,可以在TodoList渲染列表前,先把userInput为空/null的项过滤掉:

// TodoList组件里的map改成
{todos?.filter(todo => todo.userInput?.trim()).map((todo,index) => {
  return (
   <li key={index} >
     <TodoItem todo={todo} index={index} removeItem={removeItem} markItem={markItem} />
  </li>
  )
})}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 03:50:29