我们之前已经实现了静态的组件拆分,既然是静态说明数据就是死的,显然这不是我们需要的结果,之前我们学习了React
组件,知道组件里面的状态数据驱动了页面的显示,每个组件都有属于自己的状态数据。接下来我们改造组件使得组件有自己的状态数据。
分析组件之间的关系
首先我们知道Todolist
案例的主要功能是:通过Header组件输入任务项添加任务,在由List组件展示任务项。
思考1:Header
组件和List
组件可以通信吗?现目前好像不能实现兄弟组件的通信。
思考2:Header
组件和List
组件可以和谁通信?好像是App
组件,因为它们是父子关系。
思考3: 我们可以通过App
组件建立Header
和List
组件之间的数据交互吗?好像可以。
根据上图以及我们所学知识,可以知道父子组件可以通过props
标签属性来进行组件之间的通信。那么我们可以让父组件的状态数据成为一个公共数据,可以同时传递给Header组件和List组件使用。
尝试编写代码
App
组件
import React, { Component } from 'react' import Header from "./components/Header" import List from "./components/List" import Footer from "./components/Footer" import "./index.css" export default class App extends Component { // 定义列表的初始状态数据 state = {todos: [ {id:'001',name:'吃饭',done: true}, {id:'002',name:'睡觉',done: true}, {id:'003',name:'写代码',done: false}, ]} render() { const { todos } = this.state return ( <div className="todo-container"> <div className="todo-wrap"> <Header/> <List todos={todos}/> <Footer/> </div> </div> ) } }
我们在App
组件中定义了任务列表的初始状态数据,并把该数据使用props
的方式传入了List
组件。
List
组件
import React, { Component } from 'react' import Item from '../Item' import "./index.css" export default class List extends Component { render() { const {todos} = this.props return ( <ul className="todo-main"> { todos.map(todo=>{ return <Item key={todo.id} {...todo}/> }) } </ul> ) } }
我们在List
组件中接收到了由App
组件传递的数据,且遍历该数据,把单个任务项的数据以批量传递的形式{...todo}
交给组件Item
。
Item
组件
import React, { Component } from 'react' import "./index.css" export default class Item extends Component { render() { const {name,done} = this.props return ( <li > <label> <input type="checkbox" defaultChecked={done}/> <span>{name}</span> </label> <button className="btn btn-danger" style={{display:"none"}}>删除</button> </li> ) } }
在Item
组件接收到props
数据后,拿到name
值放到span
标签中进行展示,done
值交给复选框的defaultChecked
属性,用于展示任务项的默认状态是否被选中。
- 查看效果
至此我们就完成数据在组件的动态传递,他们的传递方式是通过props
。