本小节,我们来实现最后的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
中的defaultChecked
与checked
属性的区别
defaultChecked
和checked
是React
中用于处理表单元素的两个属性。它们之间的区别在于:
defaultChecked
是用于设置表单元素的默认选中状态的属性。当组件首次渲染时,如果没有传递checked
属性,则会使用defaultChecked
属性来设置表单元素的选中状态。如果传递了checked
属性,则defaultChecked
属性将被忽略。
checked
是用于设置表单元素的选中状态的属性。当组件渲染时,如果传递了checked
属性,则会使用该属性来设置表单元素的选中状态。如果没有传递checked
属性,则会使用defaultChecked
属性来设置表单元素的选中状态。
简单的说: defaultChecked
属性 用于设置复选框的 默认选中状态,而 checked
属性 用于设置复选框的 当前选中状态。当复选框的选中状态发生变化时,我们使用onChange
事件处理程序来更新组件的状态 。checked
属性要配合onChange
事件处理一起使用,不然react会报错。