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}>&#xd7;</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;

上一篇 下一篇

猜你喜欢

热点阅读