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

React Todo列表:localStorage更新滞后及输入框无法清空问题

React Todo列表:localStorage更新滞后、输入框无法清空的解决办法

问题根源

  1. React状态更新的异步性:setTodos是异步操作,调用它之后立刻读取todos变量,拿到的还是更新前的旧数组,所以存到localStorage的永远是上一次的旧数据,自然会滞后一步。
  2. 输入框未做双向绑定:你的TextField只加了onChange但没绑定value属性,就算调用setTodoEntry('')更新了状态,输入框的视图也不会同步清空。

修复方案

1. 用useEffect监听todos变化,自动同步到localStorage

把localStorage的更新逻辑从handleSubmit里抽出来,用useEffect监听todos状态的变化,只要状态更新,就自动同步到本地存储,彻底避开异步问题。

2. 给TextField绑定value属性

把todoEntry状态和输入框的value绑定,实现双向数据绑定,这样调用setTodoEntry('')时输入框才会同步清空。

3. 用函数式更新setTodos

在更新todos时依赖当前状态的场景下,用函数式更新的写法能确保拿到最新的状态值,避免状态不一致。

修改后的完整代码

import { useState, useEffect } from 'react'
import './App.css'
import Todo from './components/todo'
import { TextField, Button } from '@mui/material';
import { nanoid } from 'nanoid';

function App() {
  let myStoredTodos = localStorage.getItem('todos');
  const [todos, setTodos] = useState(myStoredTodos ? JSON.parse(myStoredTodos) : []); 
  const [todoEntry, setTodoEntry] = useState('');
  
  // 监听todos变化,自动同步到localStorage
  useEffect(() => {
    localStorage.setItem('todos', JSON.stringify(todos));
  }, [todos])
  
  function handleTodoEntry(event) {
    setTodoEntry(event.target.value);
  }

  function handleSubmit(event) {
    event.preventDefault();
    if (!todoEntry) return;
    // 函数式更新,确保拿到最新的todos状态
    setTodos(prevTodos => [ 
      { id: nanoid(), checked: false, value: todoEntry }, 
      ...prevTodos 
    ])
    setTodoEntry('');
  }

  return (
    <>
      <h1>{`//TODO`}</h1>
      <form onSubmit={handleSubmit}>
        {/* 绑定value属性,实现双向绑定 */}
        <TextField 
          variant="standard" 
          onChange={handleTodoEntry} 
          value={todoEntry}
        />
        <Button id="add-button" type="submit" variant="contained" disabled={!todoEntry.length}>Add</Button>
      </form>
      
      <ul>
        {todos.map((todo) => (
          <li key={todo.id}>
            <Todo checked={todo.checked} value={todo.value} />
          </li>
        ))}
      </ul>
    </>
  )
}

export default App;

关键改动说明

  • 新增useEffect,依赖todos状态,每次状态更新就同步到localStorage,彻底解决异步导致的滞后问题。
  • TextField添加value={todoEntry},实现双向绑定,输入框会跟随状态变化清空。
  • setTodos改用函数式更新,传入prevTodos参数,确保拿到的是最新的状态数组,避免因异步导致的状态不一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 15:22:51