(精华)2020年7月26日 React Todolist的实现

95 阅读1分钟

app.js

import React from 'react'
import TodoMain from './components/TodoMain';
import TodoHeader from './components/TodoHeader';
import TodoFooter from './components/TodoFooter';
class App extends React.Component{
   constructor(props){
    super(props)
    this.state = {
      todos:[],
      isAllChecked:false
    }
   }
    addTodo = (todoItem)=>{
      this.state.todos.push(todoItem)
      // 
      this.setState({
        todos:this.state.todos
      })
    }
    deleteTodo = (index)=>{
      this.state.todos.splice(index,1)
      this.setState({
        todos:this.state.todos
      })
    }
    changeTodoState = (index,isDone)=>{
      this.state.todos[index].isDone = isDone
      let isAllChecked = false
      if(this.state.todos.every(todo=>todo.isDone)){
        isAllChecked = true
      }
      this.setState({
        todos:this.state.todos,
        isAllChecked
      })
    }
    changeTodoStateAll = (isDone) =>{
      this.setState({
        todos:this.state.todos.map((todo)=>{
          todo.isDone = isDone;
          return todo
        }),
        isAllChecked:isDone
      })
    }
    clearDone = ()=>{
      // 
      let todos = this.state.todos.filter(todo=>!todo.isDone)
      this.setState({
        todos,
        isAllChecked:false
      })
    }
    render(){
        const {todos,isAllChecked} = this.state;
        let info = {
          todoCount:todos.length || 0,
          todos,
          todoDoneCount:(todos && todos.filter((todo)=>todo.isDone)).length || 0,
          isAllChecked
        } 
        return(
          <div className="todo-wrap">
                <TodoHeader addTodo = {this.addTodo}/>
                <TodoMain {...info} deleteTodo = {this.deleteTodo} changeTodoState={this.changeTodoState}/>
                <TodoFooter {...info} changeTodoStateAll={this.changeTodoStateAll} clearDone={this.clearDone}/>
          </div>
        );
    }
}
export default App;

todomain.js

import React from 'react';
import TodoItem from './TodoItem';
export default  class TodoMain extends React.Component{
    render() {
        const {todos,todoCount,todoDoneCount} = this.props
        if(todos.length == 0){
            return <div class="todo-empty">
                恭喜你没有代办事项
            </div>
        }else{
            return (
                <ul className="todo-main">
                    {
                        todos.map((todo,index)=>{
                            return <TodoItem  text={todo.text} key={index} isDone={todo.isDone} index={index} {...this.props}/>
                        })
                    }
                    <li className="item">
                        <label>
                          <span><strong>{todoCount}</strong>总数/<strong>{todoDoneCount}</strong>已完成</span>
                        </label>
                    </li>
                </ul>
            )
        }
             
    }
}

todoitem

import React from 'react';
export default class TodoItem extends React.Component{
    state = {
        isShow:false
    }
    handelMouseOver = ()=>{
        this.setState({
            isShow:true
        })
    }
    handelMouseOut = ()=>{
        this.setState({
            isShow:false
        })
    }
    handelDelete = ()=>{
        this.props.deleteTodo(this.props.index)
    }
    handelChange = ()=>{
        let isDone = !this.props.isDone;
        this.props.changeTodoState(this.props.index,isDone)
    }
    render(){
        const {isShow} = this.state
        const {text,isDone} = this.props
        const taskDone = isDone ? "task-done" : ''
        return(
            <li className="list-group-item-success item" onMouseOver={this.handelMouseOver} onMouseOut={this.handelMouseOut}>
                 <label>
                     <input type="checkbox" checked={this.props.isDone} className="pull-left" onChange={this.handelChange}/>
                     <span className={taskDone}>{text}</span>
                 </label>
                <div className="pull-right">
                    <button type="button" className={isShow ? "btn btn-xs" : "btn btn-xs close"} onClick={this.handelDelete}>删除</button>
                </div>
            </li>
        )
    }
}

todoheader.js

import React from 'react';
class TodoHeader extends React.Component{
    handelKeyUp = (e)=>{
        // 获取input的值
        if(e.keyCode == 13){
            let value = e.target.value;
            if(!value) return false
            let newTodoItem = {
                text:value,
                isDone:false
            }
            e.target.value = ''
            // 调用父组件传过来的方法
            this.props.addTodo(newTodoItem)
        }
        
    }
    render() {
        return(
            <div className="todo-header">
                <h1 className="text-center">React Todo</h1>
                <div className="form-horizontal">
                    <div className="form-group">
                    <label className="col-md-2 control-label">Task</label>
                    <div className="col-md-10">
                      <input type="text" onKeyUp={this.handelKeyUp} placeholder="请输入你的任务名称,按回车键确认" className="form-control"/>
                    </div>
                    </div>
                </div>
            </div>
        )
    }
};
export default TodoHeader;

todofooter.js

import React from 'react';
export default class TodoFooter extends React.Component{
    handelSelectAll = (e)=>{
        this.props.changeTodoStateAll(e.target.checked)
    }
    handelDeleteDone = ()=>{
        this.props.clearDone()
    }
    render(){
            return(
                <div className="todo-footer">
                    <label>
                        <input type="checkbox"  checked={this.props.isAllChecked} onChange={this.handelSelectAll}/>全选
                    </label>
                    <div className="clearTask">
                        <button className="btn" onClick={this.handelDeleteDone}>清除已完成任务</button>
                    </div>
                </div>
            )
    }
}