javascript - 反应类组件。待办事项应用程序。如何使用 localStorage 存储数据
问题描述
我想用 localStorage 存储待办事项数据,这样刷新页面后它就不会消失。我在开始创建时使用了 React 类组件。
我添加了“handleFormSubmit”和“ComponentDidMount”方法。
- 当我输入 todo 并选择日期时,localStorage 中没有任何内容。
- 使用 Line 'const result = localData 在 ComponentDidMount 中得到错误?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
解决方案
当您按下按钮时,您将尝试调用两个事件 - addTodo 和 handleFormSubmit。由于您
e.preventDefault()
在 addTodo 中调用,因此永远不会调用提交事件。您可以在其中一种方法中执行您需要的所有操作。我的猜测是您要么尝试 JSON.parse 一个数组而不是一个对象,要么 的值
todo
未定义。您正试图todo
摆脱this.state
,但您只有todos
在您的状态下,所以这可能是一个错字。也是如此deadline
。您正在进行设置并正确设置。即使您第一次在构造函数中设置状态,您实际上也可以从 localStorage 获取数据。但是您尝试的 componendDidMount 方法也很好。
constructor(props) {
super(props)
const cachedTodos = localStorage.getItem("todo")
this.state = {
todos: cachedTodos ?? todosData,
...
}
推荐阅读
- typo3-extensions - Typo3/FLUID 中的 Action Links 参数是否有长度限制?
- html - 按钮悬停显示模式禁用实际按钮
- javascript - 在详细信息页面上制作订单按钮-Django
- sql - 如何在 Oracle SQL 中搜索特定的 XML 值?
- flutter - Flutter:如何在 Web 和 Windows 上启用触摸手势(自更新 2.5 起)
- python - Google Ads API v8 - 将细分字段放入查询中
- java - Blaze-Persistence Querydsl 集成是否支持投影?
- express - 将 Passport 与 Express 一起使用时,Cookie 未存储在浏览器中
- microsoft-graph-api - 如何在 Microsoft Outlook 日历中检索有关特定房间事件的所有事件信息?
- python - 无法再在 tbody 中找到 tr