react——一个todolist的demo

代码如下:

function ToDoListHeader(props) {
    return <h1 className={props.className}>ToDoList</h1>
}
class CheckAll extends Component{
    changeAll(event){
        this.props.selectedChange('all',event.target.checked);
    }
    batchDel(){
        this.props.batchDel();
    }
    render(){
        if(this.props.totalLen > 0){
            return <div className="ctr">
                <label htmlFor="all">
                    <input type="checkbox" id="all" onChange={this.changeAll.bind(this)} checked={this.props.totalLen <= this.props.selectedLen}/>
                    {this.props.totalLen <= this.props.selectedLen ? '取消全选' :'全选'}
                </label>
                <span className="batchDel" onClick={this.batchDel.bind(this)}>批量删除</span>
            </div>
        } else {
            return null;
        }
    }
}
class InputBox extends Component{
    constructor(props){
        super(props);
        this.state = {
            value:''
        }
    }
    handleKeyDown(event){
        if(event.keyCode === 13 && this.state.value.replace(/\s/g,'').length > 0){
            this.setState({
                value:''
            });
            this.props.addToDoList(this.state.value);
        }
    }
    handleChange(event){
        this.setState({
            value:event.target.value
        })
    }
    render(){
        return (
            <from className="inputBox">
                <input type="text" className="input" value={this.state.value} onKeyDown={this.handleKeyDown.bind(this)} onChange={this.handleChange.bind(this)} placeholder="请输入..."/>
                <CheckAll totalLen={this.props.totalLen} selectedChange={this.props.selectedChange} selectedLen={this.props.selectedLen} batchDel={this.props.batchDel}/>
            </from>
        )
    }
}
class ToDoItem extends Component{
    delItem(){
        this.props.delToDoItem(this.props.index);
    }
    changeCheck(event){
        this.props.changeCheck(this.props.index,event.target.checked);
    }
    render(){
        return <li>
            <input type="checkbox" onChange={this.changeCheck.bind(this)} checked={this.props.checked}/>
             <span>{this.props.label}</span>
            <span className="del" onClick={this.delItem.bind(this)}>X</span>
            </li>
    }
}
class ToDoList extends Component{
    render(){
        const listItem = Object.keys(this.props.listItems).map((key) => {
            return <ToDoItem label={this.props.listItems[key]} key={key} index={key} delToDoItem={this.props.delToDoItem} changeCheck={this.props.changeCheck} checked={this.props.selectedList[key]}/>
        });
        return <ul className="list">{listItem}</ul>
    }
}
function ListFooter(props) {
    return <span className="info">一共{props.length}条</span>
}
class ToDoListBox extends Component{
    constructor(props){
        super(props);
        this.state = {
            // 列表
            list:{},
            // 被选中的列表项 {0:true,1:true}
            selectedList:{}
        }
    }
    // 向列表中添加条目
    addToDoList(item){
        this.setState((prevState) => {
            // 保证列表中的key不会重复
            const keys = Object.keys(prevState.list).sort();
            const nextKey = keys.length > 0 ? keys[keys.length-1] * 1 + 1 : 0;
            const list = Object.assign(prevState.list,{[nextKey]:item});
            return {
                list:list
            }
        })
    }
    // 从列表中删除条目
    delToDoItem(index){
        this.setState((prevSate) => {
            delete prevSate.list[index];
            return {
                list:prevSate.list
            }
        });
        this.selectedChange(index,false)
    }
    // 批量删除
    batchDel(){
       Object.keys(this.state.selectedList).forEach((key) => {
           this.delToDoItem(key);
           this.selectedChange(key,false);
       })
    }
    selectedChange(key,checked){
        // 取消全选
      if(key === 'all' && !checked){
          this.setState({
              selectedList:{}
          });
          return;
      }
      // 全选
      if(key === 'all' && checked){
         const list = this.state.list;
         let selectObj = {};
         Object.keys(list).forEach((key) => {
             selectObj[key] = true
         });
          this.setState({
              selectedList:selectObj
          });
          return;
      }
      // 选择或取消选择某一个
      this.setState((prevState) => {
          if(checked && !prevState.selectedList[key]){
              return {
                  selectedList:Object.assign(prevState.selectedList,{[key]:true})
              }
          }
          if(!checked && prevState.selectedList[key]){
              delete prevState.selectedList[key];
              return {
                  selectedList:prevState.selectedList
              }
          }
      })
    }
    render(){
        const selectedLen = Object.keys(this.state.selectedList).length;
        const listLen = Object.keys(this.state.list).length
        return (
            <div>
                <InputBox
                    addToDoList={this.addToDoList.bind(this)} totalLen={listLen}
                    selectedLen={selectedLen} selectedChange={this.selectedChange.bind(this)} batchDel={this.batchDel.bind(this)}/>
                <ToDoList listItems={this.state.list} delToDoItem={this.delToDoItem.bind(this)} changeCheck={this.selectedChange.bind(this)} selectedList={this.state.selectedList}/>
                <ListFooter length={listLen}/>
            </div>
        )
    }
}
class App extends Component {
  render() {
    return (
        <div className="warp">
            <logo/>
            <ToDoListHeader className="header"/>
            <ToDoListBox/>
        </div>
    );
  }
}

 

posted @ 2017-09-17 20:14  QxQstar  阅读(584)  评论(0编辑  收藏  举报