一,组件通讯介绍
基本概念:
组件是独立且封闭的单元,默认情况下,只能使用组件自己的数据。
在组件化过程中,我们将一个完整的功能拆分成多个组件,以更好的完成整个应用的功能。
而在这个过程中,多个组件之间不可避免的要共享某些数据
为了实现这些功能,就需要打破组件的独立封闭性
,让其与外界沟通。这个过程就是组件通讯
二,主要讲三种常用的组件通讯方式
父子组件之间
兄弟组件之间
跨组件层级
格式:
父组件传入数据
<子组件 自定义属性1={值1} 自定义属性2={值2} .... />
子组件两种方式接收数据:
a.函数式组件-接收数据
// 接收数据: 函数组件需要通过补充形参来获取
function 子组件(props) {
console.log('从父组件中传入的自定义属性被收集在对象:', props)
return (<div>子组件的内容</div>)
}
b.类组件-接收数据
// 接收数据: class 组件需要通过 this.props 来获取
class 子组件 extends Component {
console.log('从父组件中传入的自定义属性被收集在对象:', this.props)
render() { return (<div>子组件的内容</div>) }
}
1. 父组件向子组件通信
步骤:
父组件提供要传递的state数据
给子组件标签添加属性,值为 state 中的数据
子组件中通过 props 接收父组件中传递的数据
代码:
//父组件
export default class App extends Component {
//定义传给子组件的数据
state = {
users: [1,2,3,4]
}
render() {
return (
<div>
{/* 将users传递给子组件 */}
<List users={this.state.users}/>
</div>
)
}
}
//子组件
export default class List extends Component {
render() {
// 接收父组件传来的东西
let {users} = this.props
return (
<div>
{
users.map((item, index) => {
return (
<div key={index}>{item}</div>
)
})
}
</div>
)
}
}
2.子传父
概念:父组件将自己的某个方法传递给子组件,在方法里可以做任意操作,比如可以更改状态,子组件通过this.props
接收到父组件的方法后调用。
步骤
- 父组件
- 定义一个回调函数f(将会用于接收数据)
- 将该函数f作为属性的值,传递给子组件
- 子组件
- 通过 props 获取f
- 调用f,并传入将子组件的数据
3.兄弟组件(状态提升)
状态提升:将共享状态提升到最近的公共父组件中,由公共父组件管理这个状态
- 公共父组件职责:
- 提供共享状态
- 提供操作共享状态的方法
- 要通讯的子组件只需通过 props 接收状态或操作状态的方法
4.跨组件通信
react提供了Context来实现跨组件通信
定义数据源
import React , {createContext} from 'react'
let {Provider,Consumer} = createContext()
export {
Provider,//发布
Consumer//订阅
}
使用 Provider 组件包裹根组件,并通过 value 属性提供要共享的数据
import React ,{Component} from 'react'
import {Provider,Consumer} from './store'
import Son from './Son'
export default class App extends Component{
constructor(props){
super(props)
this.state={
name:'mingcen'
}
}
render(){
return (
<div>
<Provider value={this.state.name}>
<Son/>
</Provider>
</div>
)
}
}
在任意后代组件中,使用第1步中导出的Consumer组件包裹整个组件
import React,{Component} from'react'
import {Consumer} from './store'
export default class Son1 extends Component{
constructor(props){
super(props)
this.state={
name:'uuu'
}
}
render(){
return(
<div>
<Consumer>
{
(data)=>{
<div>{data.name}</div>
}
}
</Consumer>
</div>
)
}
}