1.TodoList.js代码
import React, {Component, Fragment} from 'react';
import TodoItem from './TodoItem'
import './style.css'
class TodoList extends Component{
constructor(props){
super(props);
this.state = {
inputValue:'',
list:[],
}
this.handleInputChange = this.handleInputChange.bind(this);
this.handleBtnClick = this.handleBtnClick.bind(this);
this.handleItemDelete = this.handleItemDelete.bind(this);
}
render() {
return(
<Fragment>
<div>
{/*htmlFor='insertArea'扩大点击范围到label*/}
<label htmlFor='insertArea'>输入内容</label>
<input
id="insertArea"
className='input'
value={this.state.inputValue}
onChange={this.handleInputChange}
/>
<button onClick={this.handleBtnClick}>提交</button>
</div>
<ul>
{this.getTodoItem()}
</ul>
</Fragment>
)
}
getTodoItem(){
return this.state.list.map((item, index) => {
//做循环 循环中的每一项都要有一个key值
return (
// 将子list中的item传给TodoItem
<TodoItem
key={index}
content={item}
index={index}
deleteItem={this.handleItemDelete}
/>
)
})
}
handleInputChange(e){
/**老方法*/
// this.setState({
// inputValue : e.target.value,
// })
/** 新方法提升性能 可以接收函数 小括号相当于return 就是返回里面的对象
* 写成函数变成异步的设置数据的话 需要在外面设置一下 再在里面使用
* */
const value = e.target.value;
this.setState(() => ({
inputValue:value
}));
}
handleBtnClick(){
//老方法
// this.setState({
// list:[...this.state.list, this.state.inputValue],
// inputValue:''
// })
/**
* this,setState会接收一个prevState
* prevState等价于this.state*/
//新方法 接收函数
this.setState((prevState)=>({
list:[...prevState.list,prevState.inputValue],
inputValue:''
}));
}
handleItemDelete(index){
//immutable
//state 不允许我们做任何改变
// const list = [...this.state.list];
// list.splice(index,1);
// this.setState({
// list: list
// })
// console.log(index);
/**
* 新方法*/
this.setState((prevState)=>{
const list = [...prevState.list];
list.splice(index,1);
return{list}
});
}
}
export default TodoList;
2.TodoItem.js代码
class TodoItem extends Component{
constructor(props){
super(props);
this.handleClick=this.handleClick.bind(this);
}
render() {
const {content} = this.props;
return(
<div onClick={this.handleClick}>
{/*{this.props.content}*/}
{content}
</div>)
}
handleClick(){
const {deleteItem, index} = this.props;
// this.props.deleteItem(this.props.index)
deleteItem(index);
}
}
export default TodoItem;
3.在TodoItem.js中
用ES6语法定义一个
const {content} = this.props;
用
{content}
调用,{content}就相当于
{this.props.content}
同理,
使用ES6语法定义
const {deleteItem, index} = this.props;
用
deleteItem(index);
调用,deleteItem(index);相当于
this.props.deleteItem(this.props.index)
4.TodoList.js代码中 提升性能部分
1.在constractu中定义所有this.handleInputChange.bind(this);写法,如下
this.handleInputChange = this.handleInputChange.bind(this);
这样的写法改变作用域的话,可以保证整个程序里这个作用域的绑定值执行一次,而且可以避免子组件的一些无畏渲染,提升性能。
2.setState方法中,将以下
this.setState({
inputValue : e.target.value,
})
替换为新版 新方法提升性能 可以接收函数 小括号相当于return 就是返回里面的对象
写成函数变成异步的设置数据的话 需要在外面设置一下 再在里面使用
const value = e.target.value;
this.setState(() => ({
inputValue:value
}));
同理
const list = [...this.state.list];
list.splice(index,1);
this.setState({
list: list
})
改写为
this.setState((prevState)=>{
const list = [...prevState.list];
list.splice(index,1);
return{list}
});
this.setState会接收一个prevState
prevState等价于this.state
3.生命周期中 提升性能避免不必要的渲染
shouldComponentUpdate(nextProps, nextState, nextContext) {
//nextProps指的是接下来我的props会变成什么样
//nextState指的是接下来我的state会变成什么样
//如果我接下来的props里的content不等于当前prop里面的content 则需要渲染
if (nextProps.content !== this.props.content){
return true;
} else {
return false;
}
}