拆分以上内容,将list中的每一个项目拆成一个组件,将Input拆成一个组件
一、将list中的item拆成一个组件
- 新建一个文件:TodoItem.js
初始的TodoItem.js代码如下:
import React, {Component} from "react";
class TodoItem extends Component {
render() {
return <li>this is an item</li>
}
}
export default TodoItem;
- 在TodoList.js中引入
import TodoItem from './TodoItem';
- 用组件替换原来li标签的位置
<ul>
{
this.state.list.map((value,index) => {
return <TodoItem />
})
}
</ul>
注:但此时每添加一条都是一样的内容,即‘this is an item’
因为在TodoItem中该值是固定的
- 父组件命名一个属性,然后给子组件传递内容
<ul>
{
this.state.list.map((value,index) => {
return <TodoItem content={value}/>
})
}
</ul>
注:此处content为任意命名的
5. 子组件接收父组件传来的content属性值
class TodoItem extends Component {
render() {
return <li>{this.props.content}</li>
}
}
注:以上实现新增list item功能,接下来实现点击item删除功能
6. 对TodoItem中的li标签添加事件绑定:
import React, {Component} from "react";
class TodoItem extends Component {
constructor(props) {
super()
this.handleItemClick = this.handleItemClick.bind(this);
}
handleItemClick() {
}
render() {
// 子组件通过this.props的属性,从父组件接收传递过来的值
return <li onClick = {this.handleItemClick}>{this.props.content}</li>
}
}
export default TodoItem;
- 在子组件中改变父组件的list数据:
1)通过父组件中将方法传递给子组件: 父组件TodoList.js中
<ul>
{
this.state.list.map((value,index) => {
// 父组件通过属性的形式向子组件传值
return (
<TodoItem content={value}
key={index}
index={index}
deleteFunction = {this.handleItemClick}/>
)
})
}
</ul>
2)子组件调用父组件传过去的方法:子组件TodoItem.js中
handleItemClick() {
// 改变父组件中的List数据
this.props.deleteFunction(this.props.index)
}
render() {
// 子组件通过this.props的属性,从父组件接收传递过来的值
return <li onClick = {this.handleItemClick}>{this.props.content}</li>
}
注意:父组件通过属性的形式向子组件传值
子组件想要和父组件通信,它要调用父组件传递过来的方法,同时要在父组件中绑定作用域,即绑定在父组件上
- 完整代码:
TodoList.js(父组件):
import React, {Component, Fragment} from 'react';
import TodoItem from './TodoItem';
import './style.css'
class TodoList extends Component {
constructor(props) {
super(props);
this.handleItemClick = this.handleItemClick.bind(this);
this.state = {
inputValue: '',
list: []
}
}
handleInputChange(e) {
this.setState({
inputValue: e.target.value
})
}
// 松开键盘会触发该事件
handleKeyUp(e) {
// 判断是不是点的回车键
if (e.keyCode === 13 && e.target.value !== '') {
const list = [...this.state.list, this.state.inputValue];
this.setState({
list: list,
inputValue: ''
})
}
}
// 列表点击事件
handleItemClick(index) {
const list = [...this.state.list];
list.splice(index, 1);
this.setState({
list: list
})
}
render() {
return(
<Fragment>
<label htmlFor='myInput'>请输入内容:</label>
<input id='myInput' value={this.state.inputValue} onChange={this.handleInputChange.bind(this)} onKeyUp={this.handleKeyUp.bind(this)} className = 'input'/>
<ul>
{
this.state.list.map((value,index) => {
// 父组件通过属性的形式向子组件传值
return (
<TodoItem content={value}
key={index}
index={index}
deleteFunction = {this.handleItemClick}/>
)
})
}
</ul>
</Fragment>
)
}
}
export default TodoList;
TodoItem.js(子组件)
import React, {Component} from "react";
class TodoItem extends Component {
constructor(props) {
super()
this.handleItemClick = this.handleItemClick.bind(this);
}
handleItemClick() {
// 改变父组件中的List数据
// 子组件想要和父组件通信,它要调用父组件传递过来的方法
this.props.deleteFunction(this.props.index)
}
render() {
// 子组件通过this.props的属性,从父组件接收传递过来的值
return <li onClick = {this.handleItemClick}>{this.props.content}</li>
}
}
export default TodoItem;