反应类组件。待办事项应用程序。如何使用 localStorage 存储数据

Posted

技术标签:

【中文标题】反应类组件。待办事项应用程序。如何使用 localStorage 存储数据【英文标题】:React class component. Todo app. How to store data with localStorage 【发布时间】:2021-05-03 09:22:05 【问题描述】:

我想用 localStorage 存储待办事项数据,这样刷新页面后它就不会消失。 我在开始创建时使用了 React 类组件。

我添加了“handleFormSubmit”和“ComponentDidMount”方法。

    当我输入 todo 并选择日期时,localStorage 中没有任何内容。 在 ComponentDidMount 中出现错误 行 'const 结果 = localData ? JSON.parse(localData) : [];' :SyntaxError: JSON.parse: JSON 数据的第 1 行第 1 列出现意外字符 如何设置和获取项目?

如果我能得到帮助,我将不胜感激。 我想让这个应用真正发挥作用。

import React from "react"
import TodoItem from "./components/TodoItem"
import todosData from "./components/todosData"

class App extends React.Component 
    constructor(props) 
        super(props)
        this.state = 
            todos: todosData,
            //setTodos: todosData,
            newItem: "",
            deadline: "",
            editing: false
        

        this.handleChange = this.handleChange.bind(this)
        this.addTodo = this.addTodo.bind(this)
        this.updateInput = this.updateInput.bind(this)
        this.deleteItem = this.deleteItem.bind(this)
        this.updateItem = this.updateItem.bind(this)
        this.updateDeadline = this.updateDeadline.bind(this)
        this.updateInputDeadline = this.updateInputDeadline.bind(this)
        this.editItem = this.editItem.bind(this)
        this.handleFormSubmit = this.handleFormSubmit.bind(this)
    

    handleChange(id) 
      this.setState((prevState) => 
        const updatedTodos = prevState.todos.map((todo) => 
          if (todo.id === id) 
            return  ...todo, completed: !todo.completed ;
           else 
            return todo;
          
        );
        return  todos: updatedTodos ;
      );
    

    addTodo(e) 
      e.preventDefault();
      const newTodo = 
        id: this.state.todos.length + 1,
        text: this.state.newItem,  
        completed: false,
        deadline: this.state.deadline
      
      const newTodos = this.state.todos.concat([newTodo]);
      this.setState(
        todos: newTodos
      )
    

    updateInput(value, id) 
        this.setState((prevState) => 
        const updatedTodos = prevState.todos.map((todo) => 
          if(todo.id === id) 
            return ...todo, text: value
          else 
            return todo;
          
        )
        return todos: updatedTodos
      )
    

    updateInputDeadline(value, id) 
        this.setState((prevState) => 
        const updatedTodos = prevState.todos.map((todo) => 
          if(todo.id === id) 
            console.log(value, id);
            return ...todo, deadline: value
          else 
            return todo;
          
        )
        return todos: updatedTodos
      )
    

    updateItem(e) 
      this.setState(
        newItem: e.target.value
      )
    

    updateDeadline(e) 
      this.setState(
        deadline: e.target.value
      )
    

    deleteItem(id)
    const filteredItems= this.state.todos.filter(item =>
      item.id!==id); 
      this.setState(
      todos: filteredItems
    )
  

  editItem(id) 
    this.setState(
      editing: id
    )
  

  handleFormSubmit() 
    const  todo, deadline  = this.state;
    localStorage.setItem('todo', JSON.stringify(todo));
    localStorage.setItem('deadline', deadline);
  ;

  componentDidMount() 
    const localData = localStorage.getItem('todo');
    const result = localData ? JSON.parse(localData) : [];
    const deadlineData = localStorage.getItem('deadline');
    this.setState( result, deadlineData );

  

    render() 
        const todoItems = this.state.todos.map
        (item =>
          <TodoItem
          key=item.id
          item=item
          handleChange=this.handleChange
          addTodo=this.addTodo
          deleteItem=this.deleteItem
          updateInput=this.updateInput
          updateInputDeadline=this.updateInputDeadline
          isEdited=this.state.editing === item.id
          editItem=this.editItem
        />)


        return (
          <div className="todo-list">
          <Timer />

          <form onSubmit=this.handleFormSubmit>
            <div className="add-todo">
              <label>Add an item...</label>
              <input
                type="text"
                name="todo"
                placeholder="Type item here..."
                value=this.state.newItem
                onChange=this.updateItem
              />
            </div>

            <div className="date">
              <label htmlFor="deadline">Deadline</label>
              <input
                type="date" id="start" name="deadline"
                min="2021-01-01"
                max="2024-12-31"
                value=this.state.deadline
                onChange=this.updateDeadline
              />
            </div>

            <button type="submit" onClick=this.addTodo>Add to the list</button>
          </form>

            todoItems.length === 0 ? <p>No items</p> : null

            <div className="todoitems">
              todoItems
            </div>

          </div>
        )
    


export default App

【问题讨论】:

你能从const result = localData ? JSON.parse(localData) : [] 这一行检查result行的返回值吗? @2u4u 因为我收到错误,我将其更改为const result = localData ? localData : [] 并使用了console.log。它注销了 'Object result: "laundry" '。 【参考方案1】:

    当您按下按钮时,您会尝试调用两个事件 - addTodo 和 handleFormSubmit。由于您在 addTodo 中调用 e.preventDefault(),因此永远不会调用提交事件。您可以在其中一种方法中执行您需要的所有操作。

    我的猜测是您要么尝试 JSON.parse 数组而不是对象,要么 todo 的值未定义。您正试图从this.state 中取出todo,但您所在的州只有todos,所以这可能是一个错字。 deadline 也是如此。

    您正在进行设置并正确设置。即使您第一次在构造函数中设置状态,您实际上也可以从 localStorage 获取数据。但是您尝试的 componendDidMount 方法也不错。

constructor(props) 
        super(props)
        const cachedTodos = localStorage.getItem("todo")
        this.state = 
            todos: cachedTodos ?? todosData,
            ...
        

【讨论】:

谢谢@Aidam1。我想把所有的都放在一种方法中。 addTodo(e) e.preventDefault(); const todos, 截止日期, id, 完成 = this.state; localStorage.setItem('todos', JSON.stringify([...todos])); localStorage.setItem('deadline', 截止日期);但是,即使我单击“添加”按钮,这也不会返回列表中的待办事项。我怎样才能让它发挥作用? 在 this.state.todos 中,你有一个包含所有待办事项的数组,对吗?所以你可以把这个数组保存到localStorage。 addTodo(e) e.preventDefault(); const newTodos = ... /* put logic for updating todos here */ this.setState(todos: newTodos, () =&gt; localStorage.setItem('todos', JSON.stringify(todos: [this.state.todos]));

以上是关于反应类组件。待办事项应用程序。如何使用 localStorage 存储数据的主要内容,如果未能解决你的问题,请参考以下文章

无法从 Listview 中删除项目(待办事项列表),长按没有任何反应

待办事项列表应用程序中搜索字段文本中的每个更新的条件渲染

React Hooks with React Router v4 - 我如何重定向到另一个路由?

用户反应后删除消息

如何使用React删除待办事项列表中的项目

Vuex 模块化实现待办事项的状态管理