React学习(四)——实现TodoList父子组件通信
1.什么是组件
- 定义了组件继承于React的基本组件对象,一定要有自己的组件用于实例渲染。
- 组件通过render()方法渲染,返回一个html格式的组件以供渲染。
- 组件必须要用一个容器(div)包裹,不等各个元素节点都暴露在外面。
- 组件分为静态组件和有状态组件。有状态组件通过数据或逻辑控制组件里的内容显示,这些内容用state和setstate控制。
2.实现TodoList组件化
在上一遍文章我们实现了一个TodoList : React学习(三)——实现TodoList,接下来用组件化的方式升级TodoList,在列子中理解父子组件怎么通信。
2.1 新建文件 TodoItem.js
import React, {
Component } from "react";
class TodoItem extends Component {
render() {
return <li>TodoItem</li>;
}
}
export default TodoItem;
2.2 在 TodoList.js 中引入 TodoItem
import TodoItem from "./TodoItem";
getItem() {
return this.state.list.map((value, index) => {
return <TodoItem />;
});
}
我们就实现了不管输入什么都打印出来 “TodoItem”。
2.3 input值添加到list中:
子组件通过this.props的属性,获取从父组件接受传递过来的值。
class TodoItem extends Component {
render() {
return <li key={
this.props.index}>{
this.props.content}</li>;
}
}
getItem() {
return this.state.list.map((value, index) => {
return <TodoItem content={
value} index={
index} />;
});
}
这样就可以实现,输入框的值,添加到列表里面。
2.4 实现点击删除某一条数据
想要实现删除只要改变父组件中的list数据就可以。
而子组件想要和父组件通信,它要调用父组件传递过来的方法
.
//TodoList.js
handleItemClick(index) {
const list = [...this.state.list];
list.splice(index, 1);
this.setState({
list
});
}
getItem() {
return this.state.list.map((value, index) => {
return <TodoItem
content={
value}
index={
index} key={
index}
deleteFunction={
this.handleItemClick} />;
});
}
父组件传递给子组件一个删除的方法(deleteFunction)和索引值(index),而子组件只要调用这个方法就能删除掉点击的数据。
//TodoItem.js
class TodoItem extends Component {
constructor(props) {
super(props);
this.handleItemClick = this.handleItemClick.bind(this);
}
handleItemClick()
const {
deleteFunction, index } = this.props;
deleteFunction(index);
}
render() {
const {
content } = this.props;
return <li onClick={
this.handleItemClick}>{
content}</li>;
}
}
export default TodoItem;
完整的代码:
TodoItem.js
import React, {
Component } from "react";
class TodoItem extends Component {
constructor(props) {
super(props);
this.handleItemClick = this.handleItemClick.bind(this);
}
handleItemClick() {
// 改变父组件中的list数据
// 子组件想要和父组件通信,它要调用父组件传递过来的方法
const {
deleteFunction, index } = this.props;
deleteFunction(index);
}
render() {
// 子组件通过this.props的属性,从父组件接受传递过来的值
const {
content } = this.props;
return <li onClick={
this.handleItemClick}>{
content}</li>;
}
}
export default TodoItem;
TodoList.js
import React, {
Component, Fragment } from "react";
import "./todoList.css";
import TodoItem from "./TodoItem";
class TodoList extends Component {
//在组件创建的第一个时刻被执行
constructor(props) {
super(props);
// 创建两个数据,被定义在state中
this.handleInputChange = this.handleInputChange.bind(this);
this.handleKeyUp = this.handleKeyUp.bind(this);
this.handleItemClick = this.handleItemClick.bind(this);
this.state = {
inputValue: "",
list: []
};
}
handleInputChange(e) {
// this.state.inputValue = e.target.value;
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
list,
inputValue: ""
});
}
}
handleItemClick(index) {
const list = [...this.state.list];
list.splice(index, 1);
this.setState({
list
});
}
getItem() {
return this.state.list.map((value, index) => {
return <TodoItem content={
value} index={
index} key={
index} deleteFunction={
this.handleItemClick} />;
});
}
render() {
//普通JS注释
return (
<Fragment>
{
/* JSX注释 */}
<label htmlFor="myInput">请输入:</label>
<input id="myInput" className="input" value={
this.state.inputValue} onChange={
this.handleInputChange} onKeyUp={
this.handleKeyUp} />
<ul>{
this.getItem()}</ul>
</Fragment>
);
}
}
export default TodoList;
有缘再见ヾ( ̄▽ ̄)Bye~Bye~