第二十六章 案例TodoList 之实现Footer组件

本小节,我们来实现最后的Footer组件的功能,它的功能主要有:

  • 记录已完成全部的任务列表数量
  • 点击【复选框】可以实现全选全不选
  • 点击【删除已完成】按钮,可以将选中的任务项删除掉

实现已完成和全部的任务列表数量

步骤1:在App组件将todos的状态通过props传递给Footer组件

 <Footer todos={todos} />

步骤2:Footer组件接收数据并计算长度

export default class Footer extends Component {
  render() {
    const {todos} = this.props
    // 计算列表的长度
    const len = todos.length
    // 计算已完成的列表长度
    const doneLen = todos.reduce((pre,cur)=>{
      return pre + (cur.done ? 1:0)
    },0)
    
    return (
      <div className="todo-footer">
      <label>
        <input type="checkbox"/>
      </label>
      <span>
        <span>已完成{doneLen}</span> / 全部{len}
      </span>
      <button className="btn btn-danger">清除已完成任务</button>
    </div>
    )
  }
}

步骤3:查看效果

在这里插入图片描述

可以看到我们选中和取消选中时,已完成和全部的长度变化,和我们期望的一样。


实现【复选框】可以实现全选和全不选

  • 1、在App组件里面编写函数逻辑,并传递函数给Footer组件
  // 实现全选和全不选
  selectAllData = (done) => {
    console.log(done)
    const {todos} = this.state
    const newTodos = todos.map(todo=>{
      return {...todo,done}
    })
    this.setState({todos:newTodos})
  }
<Footer todos={todos} selectAllData={this.selectAllData} />
  • 2、给props添加限制
  // 对props做类型和必要性的限制
  static propTypes = {
    selectAllData:PropTypes.func.isRequired,
  }
  • 3、给Footer组件的复选框添加属性和事件回调
  // 全选和全不选的事件回调
  checkAllHandle = (event) => {
    this.props.selectAllData(event.target.checked)
  }
 <input type="checkbox" checked={len === doneLen && len!==0 ? true:false} onChange={this.checkAllHandle} />
  • 4、查看效果

在这里插入图片描述

为什么没有效果呢?难道是我代码写的有问题?检查了一下,代码确实有问题,但是不是这里的问题,而是在Item组件里面的复选框的defaultChecked属性的问题。我们改为checked属性就好。

<input type="checkbox" defaultChecked={done} onChange={event=>this.checkHandle(id,event)}/>

===>

<input type="checkbox" checked={done} onChange={event=>this.checkHandle(id,event)}/>

修改好后,我们再看效果:

在这里插入图片描述

我们看到已经可以全选和全不选了。


实现【删除已完成】按钮,可以将选中的任务项删除掉

  • 1、在App组件里面编写好删除已完成的列表数据的函数代码逻辑,并传递给Footer组件
  // 删除已完成的任务项
  deleteDoneData = () => {
    const {todos} = this.state
    const newTodos = todos.filter(todo=>{
      return !todo.done
    })
    this.setState({todos:newTodos})
  }
 <Footer todos={todos} selectAllData={this.selectAllData} deleteDoneData={this.deleteDoneData} />
  • 2、给props添加限制
  // 对props做类型和必要性的限制
  static propTypes = {
    selectAllData:PropTypes.func.isRequired,
    deleteDoneData:PropTypes.func.isRequired
  }
  • 3、给【删除已完成】按钮添加点击事件回调函数
// 删除已完成的任务项
  deleteDoneHandle = () => {
    this.props.deleteDoneData()
  }
<button onClick={this.deleteDoneHandle} className="btn btn-danger">清除已完成任务</button>
  • 4、查看效果

在这里插入图片描述

由图可知该功能已完成。


查看完整功能

在这里插入图片描述


小总结

  • 熟悉数组函数reduce/map/filter...
  • 了解react中的defaultCheckedchecked属性的区别

defaultCheckedcheckedReact中用于处理表单元素的两个属性。它们之间的区别在于:

defaultChecked是用于设置表单元素的默认选中状态的属性。当组件首次渲染时,如果没有传递checked属性,则会使用defaultChecked属性来设置表单元素的选中状态。如果传递了checked属性,则defaultChecked属性将被忽略。

checked是用于设置表单元素的选中状态的属性。当组件渲染时,如果传递了checked属性,则会使用该属性来设置表单元素的选中状态。如果没有传递checked属性,则会使用defaultChecked属性来设置表单元素的选中状态。

简单的说: defaultChecked属性 用于设置复选框的 默认选中状态,而 checked属性 用于设置复选框的 当前选中状态。当复选框的选中状态发生变化时,我们使用onChange事件处理程序来更新组件的状态 。checked属性要配合onChange事件处理一起使用,不然react会报错。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天界程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值