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

React todo存localStorage后刷新前端无法正常渲染问题求助

React待办应用问题修复方案

核心问题原因

  • useState初始化错误:从localStorage读取的inittodos本身就是数组类型,初始化useState时额外多套了一层数组,导致todoslist始终是二维数组结构[[todo项1, todo项2...]],遍历渲染时只能拿到外层的第一个数组元素,自然只会显示单个todo,也无法正确读取todo的属性值。
  • 组件命名不匹配:App组件中导入的组件名为Addtodo,但实际组件导出的名称是Add_todo,命名不一致会导致组件加载异常。
  • 缺失ondelete函数定义:App组件中传给Todos组件的ondelete方法没有声明,运行时会直接报错。

修复步骤

  1. 修正useState初始化逻辑,将App组件中:
const [todoslist, settodos] = useState([inittodos]);

修改为

const [todoslist, settodos] = useState(inittodos);
  1. 统一组件命名,要么将App组件的导入语句改为import { Add_todo as Addtodo } from "./my-components/addtodo";,要么直接修改Add_todo组件的导出名称为Addtodo。
  2. 在App组件中补全ondelete函数逻辑,示例如下:
const ondelete = (targetTodo) => {
  settodos(todoslist.filter(item => item.task !== targetTodo.task))
}
  1. (可选优化)修正Add_todo组件中task_name输入框的类型错误,将type="textl"改为type="text"。

修复后完整代码

App.js

import './App.css';
import Header from "./my-components/header.js";
import Todos from "./my-components/todos";
import Footer from "./my-components/footer";
import { Add_todo as Addtodo } from "./my-components/addtodo";
import React, { useState, useEffect } from 'react';
   
function App() {
  let inittodos;
  if (localStorage.getItem("todoslist") === null) {
    inittodos = [];
  } else {
    inittodos = JSON.parse(localStorage.getItem("todoslist"));
  }
  const addtodo = (task, task_name, members) => { 
    let newtodo = {
      task: task,
      task_name: task_name,
      members: members
    };
    settodos([...todoslist, newtodo]);
  }
  const ondelete = (targetTodo) => {
    settodos(todoslist.filter(item => item.task !== targetTodo.task))
  }
  const [todoslist, settodos] = useState(inittodos);
  useEffect(() => {
    localStorage.setItem("todoslist", JSON.stringify(todoslist));
  }, [todoslist]);

  return (
    <>
      <Header title="Learnig-React" search_bar={true} />
      <Addtodo addtodo={addtodo} />
      <Todos todos={todoslist} ondelete={ondelete} />
      <Footer />
    </>
  );
}
export default App;

addtodo.js

import React, { useState } from 'react'
       
export const Add_todo = ({ addtodo }) => {
  const [task, settask] = useState("");
  const [task_name, settask_name] = useState("");
  const [members, setmembers] = useState("");

  //submit function for storing contents onclick on submit button
  const submit = (e) => {
    e.preventDefault();
    if (!task || !task_name || !members) {
      alert("Plese fill all details");
    } else {
      addtodo(task, task_name, members);
      settask("");
      settask_name("");
      setmembers("")
    }
  }
  return (
    <div className="container">
      <form onSubmit={submit}>
        <div className="form-group">
          <label htmlFor="task">Task</label>
          <input type="text" id="task" className="form-control" aria-describedby="emailHelp" value={task} onChange={(e) => { settask(e.target.value) }} placeholder="Enter Task" />
          <small id="" className="form-text text-muted">We'll never share your email with anyone else.</small>
        </div>

        <div className="form-group">
          <label htmlFor="task_name">Task-Name</label>
          <input type="text" id="task_name" className="form-control" aria-describedby="emailHelp" value={task_name} onChange={(e) => { settask_name(e.target.value) }} placeholder="Enter Task Name" />
          <small id="" className="form-text text-muted">We'll never share your email with anyone else.</small>
        </div>

        <div className="form-group">
          <label htmlFor="members">Members</label>
          <input type="number" id="members" className="form-control" aria-describedby="emailHelp" value={members} onChange={(e) => { setmembers(e.target.value) }} placeholder="Enter No. Members" />
          <small id="" className="form-text text-muted">We'll never share your email with anyone else.</small>
        </div>
        <button type="submit" className="btn-sm btn-success my-3">Submit</button>
      </form>
    </div>
  )
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 15:54:04