10、没有Redux的TodoList
2020-02-17 本文已影响0人
海蒂Hedy
import React,{useEffect,useState, useCallback, useRef} from 'react';
import './App.css';
//定义全局的唯一id为时间戳
let idSep = Date.now();
function Control(props){
const {addTodo} = props;
//获取元素属性
const inputRef = useRef();
const onSubmit=(e)=>{
//阻止默认元素的提交
e.preventDefault();
//获取元素当前句柄,并且清除两边的空白
const newText = inputRef.current.value.trim();
console.log(newText);
//判断值
if(newText.length === 0){
return;
}
//创建TODO
addTodo({
id:++idSep,
text:newText,
complete:false,
});
//清空输入框
inputRef.current.value = '';
};
return (
<div className="control">
<h1>todos</h1>
<form onSubmit={onSubmit}>
<input type="text" ref={inputRef} className="new-todo" placeholder="something to do"/>
</form>
</div>
)
}
function TodoItem(props){
const {
todo:{
id,text,complete
},
toggleTodo,
removeTodo,
} = props;
const onChange=()=>{
toggleTodo(id);
}
const onRemove=()=>{
removeTodo(id);
}
return(
<li className="todo-item">
<input type="checkbox"
onChange={onChange}
checked={complete}
/>
<label className={complete?'complete':''}>{text}</label>
<button onClick={onRemove}>×</button>
</li>
)
}
function Todos(props){
const {todos,toggleTodo,removeTodo} = props;
return (
<ul>
{
todos.map(todo=>{
return(
<TodoItem
key={todo.id}
todo={todo}
toggleTodo={toggleTodo}
removeTodo={removeTodo}
/>
)
})
}
</ul>
)
}
const LS_KEY = '_todos_';
function TodoList(){
const [todos,setTodos] = useState([]);
const addTodo = useCallback((todo)=>{
setTodos(todos=>[...todos,todo]);
},[]);
const removeTodo=useCallback((id)=>{
setTodos(todos=>todos.filter(todo=>{
return todo.id !== id;
}))
},[]);//写需要依赖的参数
const toggleTodo=useCallback((id)=>{
setTodos(todos=>todos.map(todo=>{
return todo.id === id
?{
...todo,
complete:!todo.complete,
}
:todo;
}))
},[]);
//程序启动后执行一次,副作用的顺序很重要
useEffect(() => {
const todos = JSON.parse(localStorage.getItem(LS_KEY) || '[]');
setTodos(todos);
}, []);
//用两个副作用和localStorage来存储已经添加的数据,todos的变化
useEffect(()=>{
localStorage.setItem(LS_KEY,JSON.stringify(todos))
},[todos]);
return (
<div className="todo-list">
<Control addTodo={addTodo}></Control>
<Todos todos={todos} removeTodo={removeTodo} toggleTodo={toggleTodo}></Todos>
</div>
)
}
export default TodoList;