React Hooks - TodoList
App.js
import React, { useState, useCallback,useEffect } from 'react';
import TodoInput from './components/TodoInput';
import TodoList from './components/TodoList';
function App () {
const [todoList, setTodoList] = useState([]);
useEffect(()=>{
let _todoList = JSON.parse(localStorage.getItem('todoList') || '[]');
setTodoList(_todoList);
},[])
useEffect(() => {
localStorage.setItem('todoList', JSON.stringify(todoList))
}, [todoList])
const addTodoItem = useCallback((todoItem) => {
setTodoList(todoList => [todoItem, ...todoList])
}, [])
const setCompleted = useCallback((id) => {
setTodoList(todoList => {
return todoList.map(item => {
if (item.id === id) {
item.completed = !item.completed;
}
return item;
})
})
}, [])
const removeTodoItem = useCallback((id) => {
setTodoList(todoList => {
return todoList.filter((item) => {
return item.id !== id;
})
})
}, [])
return (
<div className="app">
<TodoInput
addTodoItem={addTodoItem}
/>
<TodoList
todoList={todoList}
setCompleted={setCompleted}
removeTodoItem={removeTodoItem}
/>
</div>
)
}
export default App;
src / components/TodoInput.js
import React, { useRef } from 'react';
function TodoInput(props){
const inputRef = useRef(),
{ addTodoItem } = props;
const addTodo = () => {
const _val = inputRef.current.value.trim();
if (_val.length === 0) {
return;
}
addTodoItem({
id: new Date().getTime(),
content: _val,
completed: false,
})
inputRef.current.value = "";
}
return (
<div>
<input
type="text"
ref={inputRef}
/>
<button onClick={addTodo}>增加</button>
</div>
)
}
export default TodoInput;
src/components/TodoList.js
import React from 'react';
function TodoList (props) {
const { todoList, setCompleted, removeTodoItem } = props;
return (
<ul>
{
todoList.map((item, index) => {
return (
<li key={index}>
<input
type="checkbox"
checked={item.completed}
onChange={() => setCompleted(item.id)}
/>
<span
style={{ textDecoration: item.completed ? 'line-through' : 'none' }}
>{item.content}</span>
<button onClick={() => removeTodoItem(item.id)}>删除</button>
</li>
)
})
}
</ul>
)
}
export default TodoList;
React class component - TodoList
App.js
import React, { Component } from 'react';
import TodoInput from './components/TodoInput';
import TodoList from './components/TodoList';
class App extends Component {
state = {
todoList: []
}
addTodoItem (todoItem) {
this.state.todoList.push(todoItem);
this.setState({
todoList: this.state.todoList
})
}
setCompleted (id) {
const todoList = this.state.todoList.map(item => {
if (item.id === id) {
item.completed = !item.completed;
}
return item;
})
this.setState({ todoList })
}
removeTodoItem (id) {
const todoList = this.state.todoList.filter(item => item.id != id);
this.setState({ todoList })
}
render () {
return (
<div className="app">
<TodoInput
addTodoItem={this.addTodoItem.bind(this)}
/>
<TodoList
todoList={this.state.todoList}
setCompleted={this.setCompleted.bind(this)}
removeTodoItem={this.removeTodoItem.bind(this)}
/>
</div>
)
}
}
export default App;
src/components/TodoInput.js
import React, { Component } from 'react';
class TodoInput extends Component {
state = {
todoValue: ''
}
setTodoValue (e) {
this.setState({
todoValue: e.target.value
})
}
addTodo () {
const _val = this.state.todoValue.trim(),
{ addTodoItem } = this.props;
if (_val.length === 0) {
return;
}
addTodoItem({
id: new Date().getTime(),
content: _val,
completed: false,
})
this.setState({
todoValue: ""
})
}
render () {
const { todoValue } = this.state;
return (
<div>
<input
type="text"
onChange={e => this.setTodoValue(e)}
value={todoValue}
/>
<button onClick={this.addTodo.bind(this)}>增加</button>
</div>
)
}
}
export default TodoInput;
src/components/TodoList.js
import React, { Component } from 'react';
class TodoList extends Component {
render () {
const { todoList, setCompleted, removeTodoItem } = this.props;
return (
<ul>
{
todoList.map((item, index) => {
return (
<li key={index}>
<input
type="checkbox"
checked={item.completed}
onChange={() => setCompleted(item.id)}
/>
<span
style={{ textDecoration: item.completed ? 'line-through' : 'none' }}
>{item.content}</span>
<button onClick={()=>removeTodoItem(item.id)}>删除</button>
</li>
)
})
}
</ul>
)
}
}
export default TodoList;