课程名称
课程章节
第3章 React基础精讲
- 3-3 实现 TodoList 新增删除功能
课程讲师
课程内容
- 实现TodoList新增删除功能
-
新增功能
不要关注dom如何操作的,只需要关注数据就够了。实际就是把inputValue的内容放入到数组list中即可,数组里有内容,页面就会跟着变化,这就实现了新增功能了。 -
删除功能
- 点击列表项,可以将该列表项删除出去。
- 点击列表项,可以将该列表项删除出去。
-
课程收获
实现TodoList新增删除功能
新增功能:
button绑定点击事件 => onClick,注意:React中绑定事件时“on”后的首字母必须大写。
onClick={this.handleBtnClick.bind(this)}
在事件处理函数中 => List目前是一个空数组,List里面有多少项,其实列表中就应该展示多少项,目前li中是写死的两项。其实不应该写死,ul中有多少个li,应该是由list数组决定的。
ul标签中包括花括号,代表这里面是js的表达式。
在这里通过数组的map方法,对list进行遍历,它的回调函数进行返回一个li标签,标签展示每一项的内容。
给list标签几个默认数组项,发现内容就展示出来了。
import React, { Component, Fragment } from "react";
class TodoList extends Component {
constructor(props){
super(props);
this.state = {
inputValue: "",
list: ["完成数学作业","完成语文作业"]
}
}
render(){
return (
<Fragment>
<div>
<input
value={this.state.inputValue}
onChange={this.handleInputChange.bind(this)}
></input>
<button onClick={this.handleBtnClick.bind(this)}>提交</button>
</div>
<ul>
{
this.state.list.map((item) => {
return <li>{item}</li>
})
}
</ul>
</Fragment>
)
}
handleInputChange(e){
this.setState({
inputValue: e.target.value
})
}
handleBtnClick(){
}
}
export default TodoList;
新增功能的实现:
不要关注dom如何操作的,只需要关注数据就够了。实际就是把inputValue的内容放入到数组list中即可,数组里有内容,页面就会跟着变化,这就实现了新增功能了。
handleBtnClick(){
this.setState({
list:[...this.state.list, this.state.inputValue]
})
}
完整代码:
import React, { Component, Fragment } from "react";
class TodoList extends Component {
constructor(props){
super(props);
this.state = {
inputValue: "",
list: ["完成数学作业","完成语文作业"]
}
}
render(){
return (
<Fragment>
<div>
<input
value={this.state.inputValue}
onChange={this.handleInputChange.bind(this)}
></input>
<button onClick={this.handleBtnClick.bind(this)}>提交</button>
</div>
<ul>
{
this.state.list.map((item) => {
return <li>{item}</li>
})
}
</ul>
</Fragment>
)
}
handleInputChange(e){
this.setState({
inputValue: e.target.value
})
}
handleBtnClick(){
this.setState({
list:[...this.state.list, this.state.inputValue]
})
}
}
export default TodoList;
功能还不够完善,最好提交之后,将input框里的内容也清空了。
handleBtnClick(){
this.setState({
list:[...this.state.list, this.state.inputValue],
inputValue:""
})
}
其实一直还会发现控制台有一个警告。
原因:在循环列表中,注意需要给循环的每一项li加一个key值,它是该项标识符,并且是唯一的,这里可以使用index下标作为它的key值。实际编程是不允许用index作为key值的,这个以后再说明。这里所有li标签,它的index都是不同的,暂时是没有问题的。
<ul>
{
this.state.list.map((item,index) => {
return <li key={index}>{item}</li>
})
}
</ul>
综上,新增的功能就完成了。
删除功能:点击列表项,可以将该列表项删除出去。
生成li的时候,给每个li绑定一个事件 => onClick={this.handleDelete.bind(this)}
handleDelete =>
点击item的时候,获取到该数组的下标,可以在bind的时候传递一个index参数,在事件处理函数就可以接收到index了。删除节点不要操作dom,还是操作数据,就是删除对应list的对应项即可。
可以先定义一个临时常量存储list,即拷贝。利用数组splice方法删除对应项。最后再调用setState方法即可。
import React, { Component, Fragment } from "react";
class TodoList extends Component {
constructor(props){
super(props);
this.state = {
inputValue: "",
list: ["完成数学作业","完成语文作业"]
}
}
render(){
return (
<Fragment>
<div>
<input
value={this.state.inputValue}
onChange={this.handleInputChange.bind(this)}
></input>
<button onClick={this.handleBtnClick.bind(this)}>提交</button>
</div>
<ul>
{
this.state.list.map((item,index) => {
return <li key={index} onClick={this.handleDelItem.bind(this, index)}>{item}</li>
})
}
</ul>
</Fragment>
)
}
handleInputChange(e){
this.setState({
inputValue: e.target.value
})
}
handleBtnClick(){
this.setState({
list:[...this.state.list, this.state.inputValue],
inputValue:""
})
}
handleDelItem(index){
const dest = [...this.state.list];
dest.splice(index, 1);
this.setState({
list: dest
})
}
}
export default TodoList;
有的人会问,为啥定一个临时常量,而不是直接操作this.state.list,试一下,这样这样直接改是不行的,而需要直接调用setState方法,可能有人说可以直接改完调用setState方法,这样也不会报错。这样的使用绝对是错误的,React当中有一个概念,immutable,它的意思是,state不允许我们做任何的改变,因此之前的临时变量(副本),就是操作临时变量(副本),而不是直接修改state变量。
注意:直接修改state,后面再做React性能优化的时候,会产生问题。
handleDelItem(index){
// const dest = [...this.state.list];
// dest.splice(index, 1);
this.state.list.splice(index, 1);
this.setState({
// list: dest
list: this.state.list
})
}
实际,一个简单的todolist就做完了。