react实现todoList

首先需要依据组件的结构拆分组件
分为Header, List, LiistItem , footer组件
App为根组件
App.js

// 采用类组件的写法
import React from 'react'
// import { 
//   Hello,
//   Welcome
// } from './componnets'
import { 
  Header,
  List,
  Footer
} from './componnets'

class App extends React.Component {
  // 状态在哪里操作状态的方法就在哪里
  state = {
    list: [
      {id: '001', name: '吃饭', todo: false },
      {id: '002', name: '睡觉', todo: true },
      {id: '003', name: '敲代码', todo: true },
      {id: '004', name: '打豆豆', todo: false },
      {id: '005', name: '打游戏', todo: true }
    ]
  }
  // 添加
  AddList = (name1) => {
    let {list} = this.state;
    console.log('name===', name1)
     this.setState({
       list: [name1, ...list]
     })
  }
  // 更新
  upDateList = (done, id) => {
    let {list} = this.state;
    let newList = list.map((item) => {
      // 选择这个的时候,勾选单选框
      if(item.id === id) return {...item, todo: done}
      else return item
    })
    console.log("newList===", newList)
    this.setState({
      list: newList
    })
  }
  //  删除
  delteUpList = (id) => {
    let { list } = this.state;
    // 删除list的某一项
    let newList = list.filter((listObj) => {
      return listObj.id !== id
    })
    this.setState({
      list: newList
    })
  }
  // 所有已经勾选的
  checkedAllTodo = (todo) => {
    let { list } = this.state
    // 加工数据
     let newArr = list.map((item) => {
       return {...item, todo}
     })
     this.setState({
       list: newArr
     })
  }
  // 清除已经完成的todolist
  clearFisahedList = () => {
    // 获取数据
    let { list } = this.state
    let newList = list.filter((item) => {
      return !item.todo
    })
    this.setState({
      list: newList
    })
  }
  render () {
    let { list } = this.state
    return <div>
      {/* <Hello/>
      <Welcome/> */}
      <Header todoList={this.AddList}/>
      <List list={list} upDateList={this.upDateList} delteUpList={this.delteUpList}/>
      <Footer list={list}
      checkedAllTodo={this.checkedAllTodo}
      clearFisahedList={this.clearFisahedList}></Footer>
    </div>
  }
}
export default App

Header组件(Header组件)

import PropTypes from 'prop-types';
import { nanoid } from 'nanoid'
import './index.css'

export default class Header extends Component {
  keyUphNA = (event) =>{
    let { keyCode,target } = event
    if (event.keyCode !== 13) return
    if (target.value.trim() === '') {
      alert('请输入添加')
      return
    }
    let obj = {id: nanoid(), name: target.value, todo: false}

    this.props.todoList(obj)
    target.value = ''
  }
  static propTypes = {
    todoList: PropTypes.func
  }
  render() {
    return (
      <div className="Header">
        <input type="text" placeholder='请输入你要输入的' onKeyUp={this.keyUphNA}/>
      </div>
    )
  }
}


List组件

import React, { Component } from 'react'
import ListItem from '../ListItem'
import PropTypes from 'prop-types';
import './index.css'

export default class List extends Component {
  static propTypes = {
     list: PropTypes.array.isRequired,
     upDateList: PropTypes.func.isRequired
  }
  render() {
    let { list, upDateList, delteUpList } = this.props
    return (
      <div className="list_container">
        {
          list.map(todo => {
            return <ListItem key={todo.id} {...todo}
            upDateList={upDateList}
            delteUpList={delteUpList}/>
          })
        }
      </div>
    )
  }
}

ListIem组件是List的子组件

import React, { Component } from 'react'
import './index.css'

export default class ListItem extends Component {
  state = {
    mouse: false
  }
  // 用同一函数采用高阶函数 进入和离开的事件
  handlermouse = (flag) => {
    return () => {
      console.log('flag===', flag)
      this.setState({
        mouse: flag
      })
    }
  }
  //  勾选和取消勾选触发的函数 
  changeHandler = (id) => {
    return (event) => {
      console.log('event, id', event.target.checked, id)
      this.props.upDateList(event.target.checked, id)
    }
  }
  deleteHandler = (id) =>{
    console.log('id====', id)
    if(window.confirm('你确定删除吗')) {
      this.props.delteUpList(id)
    }
  }
  render() {
    let { id, name, todo } = this.props
    let { mouse } = this.state
    return (
      <div className="list_item" onMouseEnter={this.handlermouse(true)}
      onMouseLeave={this.handlermouse(false)}
      style={{backgroundColor: mouse ? '#ddd': '#ccc'}}>
        <input type="checkbox" checked={todo} onChange={this.changeHandler(id)}/>
        <span>{ name }</span>
        <button style={{display: mouse ? 'block': 'none'}}
        onClick={() => this.deleteHandler(id)}>删除</button>
      </div>
    )
  }
}

Footer组件

import React, { Component } from 'react'
import './index.css'
export default class Footer extends Component {
  allChange = (event) => {
    this.props.checkedAllTodo(event.target.checked)
  }
  clearAllList = () => {
    console.log(`清除已经完成的`)
    this.props.clearFisahedList()
  }
  render() {
    let { list } = this.props;
    // 总数
    let allcount = list.length
    // 已完成的数量
    // let fished = 0;
    // for(let i =0; i<list.length; i++) {
    //   if (list[i].todo) {
    //     fished += 1
    //   }
    // }
    let fished = list.reduce((pre, current) => {
        return pre + (current.todo ? 1 : 0)
    }, 0)
    console.log('fished===', fished)
    return (
      <div className="footer">
        <input type="checkbox"
        checked={fished === allcount && allcount!==0 ? true : false}
        onChange={this.allChange}/>
        <span>已完成{fished}/总数{ allcount }</span>
        <button onClick={this.clearAllList}>清楚已完成任务</button>
      </div>
    )
  }
}

总结:
数据在哪里, 就在哪里写处理数据的方法
this.props.a 调用父组件中a的方法
react处理的三个核心: state, props, ref

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值