(TodoList.js) import React, {Component,Fragment} from 'react'; import TodoItem from './TodoItem'; import './style.css'; class TodoList extends Component { // 当我们使用组件的时候,constructor函数优于其他任何函数自动的最先被执行 constructor(props) { //super指的是调用父类的构造函数,继承经常要做的事情 super(props); //react定义数据定义在状态里 this.state = { inputValue: '', list: [] }; this.handleInputChange = this.handleInputChange.bind(this); this.handleButtonClick = this.handleButtonClick.bind(this); this.handleItemDelete = this.handleItemDelete.bind(this); } render() { return ( <Fragment> {/*{下面是一个input框}*/} <div> <label htmlFor="insertArea">输入内容</label> <input id={'insertArea'} className={'input'} value={this.state.inputValue} onChange={this.handleInputChange} /> <button onClick={this.handleButtonClick}>提交</button> </div> <ul> {this.getTodoItem()} </ul> </Fragment> ) } getTodoItem(){ return( this.state.list.map((item,index)=>{ // item是每一项的内容 // 在react里,当你做循环渲染的时候,需要给渲染出的每一项增加一个key值,这个key值每一项都应该不同,应该是每一项的标识符 return ( // {/*key值必须放在最外面一层*/} <TodoItem key={index} content={item} index={index} deleteItem = {this.handleItemDelete} /> ) }) ) } //每次输入框内输入东西,e作为事件对象会每次都输出来 handleInputChange(e) { //react给每个组件提供了setState这个方法,如果想改变state里的数据,必须调用这个方法 const value = e.target.value; // 当你把对象变成函数的时候报错时,就把target.value存在最外面一层,然后再在内层使用这个变量即可 this.setState(() => ({ inputValue: value })) } handleButtonClick(){ //setState可以接收一个参数 this.setState((prevState)=>({ list: [...prevState.list,prevState.inputValue], inputValue:'' })) } handleItemDelete(index){ //immutable //state不允许我们做任何的改变,拷贝一个副本出来 this.setState((prevState)=>{ const list = [...prevState.list]; list.splice(index,1); return {list}; }) } } export default TodoList;
(TodoItem.js)
import React,{Component} from 'react'; class TodoItem extends Component{ constructor(props){ super(props); //如果不bind,this指向会指向undefined this.handleClick = this.handleClick.bind(this); } render() { // 放在return外层,es6语法定义一个变量,结构赋值 const {content} = this.props; return ( <div onClick={this.handleClick}> {content} </div> ) } handleClick(){ const {deleteItem,index} = this.props; // 子组件被点击的时候,调用父组件传过来的deleteItem这个方法,同时把父组件传递过来的index以参数的形式传给这个方法 deleteItem(index); } } export default TodoItem;