react todolist 类组件及拆分

react todolist

组件容器(App.tsx)

import React,{Component} from 'react'
import Item from './js/Item'
import Footer from './js/Footer'
export default class App extends Component{
    constructor(){
        super();
        this.state={
            todoDatas:[],
            todoNum:0,
            view:"all",
            flag:false
        }
        this.addTodo=this.addTodo.bind(this);
        this.deleteTodo=this.deleteTodo.bind(this);
        this.changeHasCompleted=this.changeHasCompleted.bind(this);
        this.editTodo=this.editTodo.bind(this);
        this.viewTodo=this.viewTodo.bind(this);
        this.clearCompleted=this.clearCompleted.bind(this);
        this.allSelectAll = this.allSelectAll.bind(this);
    }
    // 改变todo的状态
    changeHasCompleted(todo){
        let {todoDatas,todoNum}=this.state;
        todoDatas=todoDatas.map(function(value,index){
            if(todo.id==value.id){
                value.hasCompleted=!todo.hasCompleted;
                if(value.hasCompleted){
                    todoNum--;
                }else{
                    todoNum++;
                }
            }
            return value;
        })
        this.setState({todoDatas,todoNum})
    }
    // 过滤todo
    viewTodo(view){
        this.setState({
            view
        })
    }
    // 修改todo
    editTodo(todo){
        let {todoDatas}=this.state;
        todoDatas=todoDatas.map((value)=>{
            if(value.id==todo.id){
                value.value=todo.value;
            }
            return value;
        });
        this.setState({todoDatas})
        return true;
    }
    // 删除todo
    deleteTodo(todo){
        let {todoDatas}=this.state;
        todoDatas=todoDatas.filter((value)=>{
            if(value.id=todo.id){
                return false;
            }else{
                return true;
            }
        })
        this.setState({todoDatas})
    }
    addTodo(e) {
        //判断如果不是回车,就不往下执行代码
        if (e.keyCode != 13) return;
        //如果文本框里面空字符串,就不往下执行代码
        if (e.target.value.trim() === "") return;

        //如果用户按的是回车并且不是空字符串,添加todo
        console.log("addTodo");
        //将状态todoDatas解构赋值到一个数组todoDatas中
        let { todoDatas, todoNum } = this.state;
        let todo = {};
        todo.id = new Date().getTime();
        //  todo {id:2131232321}
        todo.value = e.target.value.trim();
        // todo {id:2131232321,value:"asdf"}
        todo.hasCompleted = false;
        //todo {id:2131232321,value:"asdf",hasCompleted:false}
        //给解构出来的数组添加一个元素
        todoDatas.push(todo);
        todoNum++;
        //更新this.state中的todoDatas中,引发重新render
        this.setState({ todoDatas,todoNum});
        //清除文本框里面的字符串
        e.target.value = "";
    }
    // 删除已完成的todo
    clearCompleted(){
        // 数据过滤
        let {todoDatas}=this.state;
        todoDatas=todoDatas.filter((value)=>{
            if(value.hasCompleted){
                return false;
            }else{
                return true;
            }
        })
        this.setState({
            todoDatas
        })
    }
    // 全选和全不选
    allSelectAll(){
        let {todoDatas,flag,todoNum}=this.state;
        flag=!flag;
        if(flag){
            todoDatas=todoDatas.map((value)=>{
                value.hasCompleted=true;
                return value;
            })
            todoNum-0
        }else{
            todoDatas = todoDatas.map((value) => {
                value.hasCompleted = false;
                return value;
        })
        todoNum = todoDatas.length;
        }
        this.setState({ todoDatas, flag, todoNum });
    }
    render(){
        let { addTodo, deleteTodo, changeHasCompleted, editTodo, viewTodo, clearCompleted, allSelectAll}=this;
        let {todoDatas,todoNum,view}=this.state;
        let filterTodo=todoDatas.filter((todo)=>{
            switch(view){
                case 'all':
                    return true;
                case 'active':
                    return !todo.hasCompleted;
                case 'completed':
                    return todo.hasCompleted;
            }
        })
        let items=filterTodo.map((todo,index)=>{
            return <Item 
            key={todo.id} 
            todo={todo} 
            deleteTodo={deleteTodo}
            changeHasCompleted={changeHasCompleted}
            editTodo={editTodo}
            />
        });
        return(
            <section className="todoapp">
                <header>
                    <h1>Todos</h1>
                    <input type="text" 
                    className="new-todo" 
                    placeholder="What need to do"
                    onKeyUp={addTodo}
                    
                    />
                </header>
                <section className="main">
                    <input 
                        id="toggle-all"
                        type="checkbox"
                        className="toggle-all"
                        onChange={allSelectAll}
                    />
                    <label htmlFor="toggle-all"></label>
                    <ul className="todo-list">
                        {items}
                    </ul>
                </section>
                <Footer
                    todoNum={todoNum}
                    viewTodo={viewTodo}
                    clearCompleted={clearCompleted}
                />
            </section>
        )
    }
}

Item组件(todo)

import React, { Component } from 'react'

export default class Item extends Component {
    constructor(){
        super();
        this.state={
            inEdit:false, //标识是否进入编辑状态
            flag:true //标识是否可以执行onBlur处理函数中的代码
        }
        this.haddleEdit=this.haddleEdit.bind(this);
    }
    haddleEdit(){
        let {todo}=this.props;
        let {inEdit}=this.state;
        this.setState({
            inEdit:true
        },()=>{
            //将当前todo.value赋值给文本框
          this.refs.myInput.value=todo.value;
          //让文本框获的焦点:原生js的模拟触发获得焦点
          this.refs.myInput.focus();

        })
    }
    render() {
        let {todo,changeHasCompleted,editTodo,deleteTodo}=this.props;
        let {inEdit,flag}=this.state;
        let completed=todo.hasCompleted?"completed":"";
        let className=inEdit?completed+" editing":completed;
        return (
            <li className={className}>
                <div className="view">
                    <input type="checkbox" className="toggle"
                    onChange={()=>{
                        changeHasCompleted(todo);
                    }}
                    checked={todo.hasCompleted}
                    />
                    <label onDoubleClick={this.haddleEdit}>{todo.value}</label>
                    <button className="destroy" 
                      onClick={()=>{
                        deleteTodo(todo)
                      }}
                    ></button>
                </div>
                <input ref="myInput" type="text" className="edit"
                  onBlur={(e)=>{
                      if(flag){
                        console.log("onBlur");
                        todo.value=e.target.value.trim();
                        editTodo(todo);
                        this.setState({
                            inEdit:false
                        })
                      }
                  }}
                  
                  onKeyUp={(e)=>{
                    if(e.keyCode!=13 && e.keyCode!=27) return;
                   
                       if(e.keyCode===13){
                        todo.value=e.target.value.trim();
                        editTodo(todo);
                            this.setState({
                          inEdit:false
                         })
                       }

                       if(e.keyCode===27){
                          editTodo(todo);
                           this.setState({
                             inEdit:false,
                             flag:false
                           })
                           setTimeout(()=>{
                               this.setState({
                                   flag:true
                               })
                           },10)
                       }
                }}
                />
            </li>
        )
    }
}

Footer组件

import React, { Component } from 'react'

export default class Footer extends Component {
    render() {
        let{todoNum,viewTodo,clearCompleted}=this.props
        return (
            <footer className="footer">
                <span className="todo-count">
                    <strong>{todoNum} {todoNum > 1 ? " items left" : " item left"}</strong>
                </span>
                <ul className="filters">
                    <li><a href="#/all" onClick={()=>viewTodo("all")}>All</a></li>
                    <li><a href="#/active" onClick={() => viewTodo("active")}>Active</a></li>
                    <li><a href="#/completed" onClick={() => viewTodo("completed")}>completed</a></li>

                </ul>
                <button className="clear-completed"
                    onClick={()=>clearCompleted()}
                >Clear completed</button>
            </footer>
        )
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值