我已经用React构建了一个简单的Todo List应用。待办事项列表任务保持在数组on状态。我希望能够在刷新浏览器后保留相同的待办事项列表数组。为此,我尝试在项目中实现本地存储。将待办事项数组设置为本地存储。但是,在插入以下代码后,应用程序中断,并且我收到一条错误消息,指出props.todos.map不是函数。
componentDidMount() {
const todos = localStorage.getItem("todos");
this.setState({
...this.state.todos,
todos });
}
有人可以通过本地存储代码帮助我解决此问题吗?这是该组件(App.js)的其余代码。我将在下面包含其他组件的代码(以防万一,这有助于我找到答案),但是我可以肯定问题出在上面发布的代码片段中的App.js中。当我评论该片段时,该应用程序将恢复到以前的工作状态,但是显然,我仍然无法保持状态。
App.js:
class App extends React.Component {
constructor() {
super();
this.state = {
todos: [
{
task: "learn how to fly drone",
id: 1,
completed: false
},
{
task: "learn React class components",
id: 2,
completed: false
},
{
task: "practice editing videos",
id: 3,
completed: false
},
{
task: "read Ten Years A Nomad",
id: 4,
completed: false
}
],
todo: ''
}
}
inputChangeHandler = event => {
this.setState({[event.target.name]: event.target.value})
}
addTask = event => {
event.preventDefault();
let newTask = {
task: this.state.todo,
id: Date.now(),
completed: false
};
this.setState({
todos: [...this.state.todos, newTask],
todo: ''
})
const { todos } = this.state;
localStorage.setItem("todos", todos);
}
toggleComplete = itemId => {
const todos = this.state.todos.map(todo => {
if (todo.id === itemId) {
todo.completed = !todo.completed
}
return todo
});
this.setState({todos, todo: ''})
}
clearCompleted = e => {
e.preventDefault();
const todos = this.state.todos.filter(item => !item.completed);
this.setState({
...this.state,
todos
})
}
componentDidMount() {
const todos = localStorage.getItem("todos");
this.setState({
...this.state.todos,
todos });
}
render() {
return (
<div className="App">
<div className="header">
<h2 className="title">Welcome to your Todo App!</h2>
<TodoForm todos={this.state.todos} value={this.state.todo} inputChangeHandler={this.inputChangeHandler} addTask={this.addTask} clearCompleted={this.clearCompleted}/>
</div>
<TodoList
todos={this.state.todos}
toggleComplete={this.toggleComplete} />
</div>
);
}
}
export default App;
TodoList.js:
const TodoList = props => {
return (
<ul className="todo-list">
{props.todos.map((todo, id) => (
<Todo
todo={todo}
key={id}
toggleComplete={props.toggleComplete}
/>
))}
</ul>
)
}
export default TodoList;
Todo.js:
const Todo = props => {
return (
<li
className={props.todo.completed ? "completed-todos" : "todos"}
style={{textDecoration: props.todo.completed ? 'line-through' : 'none'}}
key={props.todo.id}
onClick={() => {
props.toggleComplete(props.todo.id)
}}
>
{props.todo.task}
</li>
)
}
export default Todo;
TodoForm.js:
const TodoForm = props => {
return (
<form className="add-form">
<input
className="add-input"
name="todo"
value={props.value}
type="text"
onChange={props.inputChangeHandler}
placeholder="Enter new task" />
<button className="add-button" onClick={props.addTask}>Add Todo</button>
<button className="clear-button" onClick={props.clearCompleted}>Clear Completed</button>
</form>
)
}
export default TodoForm;
答案 0 :(得分:1)
LocalStorage存储键值对。因此,要存储一个JavaScript对象,您需要使用JSON.stringify( object => String )进行序列化,并从localStorage中检索项目,您需要再次使用JSON.parse(字符串=>对象)
因此,如下更改addTask
和componentDidMount
:
addTask = event => {
event.preventDefault();
let newTask = {
task: this.state.todo,
id: Date.now(),
completed: false
};
this.setState(
{
todos: [...this.state.todos, newTask],
todo: ""
},
() => {
localStorage.setItem("todos", JSON.stringify(this.state.todos));
}
);
};
componentDidMount() {
const todos = localStorage.getItem("todos");
if (todos) this.setState({ todos: JSON.parse(todos) });
}
这是包含固定版本的临时sandbox