1.父组件向子组件通信
props
父组件直接通过props
向子组件传递需要的信息
import React, { Component } from 'react'
//子组件
class Child extends Component {
render() {
console.log(this.props)//{name:"React"}
return (
<div>{this.props.name}</div>
)
}
}
//父组件
export default class App extends Component {
state = {
name: "React"
}
render() {
return (
<div>
<Child name={this.state.name}></Child>
</div>
)
}
}
ref
父组件利用ref
对子组件做标记,调用子组件的方法.
import React, { Component } from 'react'
//子组件
class Child extends React.Component {
myFunc() {
return "hello"
}
render() {
return (<div>Child</div>)
}
}
//父组件
export default class App extends Component {
componentDidMount() {
var x = this.foo.myFunc() // x is now 'hello'
}
render() {
return (
<div>
<Child ref={foo => { this.foo = foo }} />
<button onClick={() => {
console.log(this.foo)//this.foo为当前Child组件的实例
console.log(this.foo.myFunc());//调用Child组件的myFunc函数
}}>Click</button>
</div>
)
}
}
2.子组件向父组件通信
回调函数
父组件通过props
传递方法下去,子组件调用这个方法。
子组件通过调用父组件传来的回调函数,从而将数据传给父组件。
import React, { Component } from 'react'
//子组件
class Child extends Component {
render() {
return (
<div>
<button onClick={() => {
this.props.func1(2)
}}>click</button>
<button onClick={() => {
this.props.func2()
}}>click</button>
</div>
)
}
}
//父组件
export default class App extends Component {
state = {
isShow: true
}
//子组件向父组件传值
handleClick = (arg)=> {
console.log(arg)//2
}
//子组件调用父组件函数改变state
handleClick1 = ()=> {
this.setState({
isShow: !this.state.isShow
},()=>{
console.log(this.state.isShow);
})
}
render() {
return (
<div>
<Child func1={this.handleClick} func2={this.handleClick1}></Child>
</div>
)
}
}
3.跨级组件通信
props逐层传递
使用props进行多级传递,但是增加了复杂度(不推荐)
import React, { Component } from 'react'
//子组件
class Son extends Component {
render() {
return (
<Child name={this.props.name}></Child>
)
}
}
//孙组件
class Child extends Component {
render() {
console.log(this.props)//{name:"React"}
return (
<div>{this.props.name}</div>
)
}
}
//父组件
export default class App extends Component {
state = {
name: "React"
}
render() {
return (
<div>
<Son name={this.state.name}></Son>
</div>
)
}
}
context
4.非嵌套关系的组件通信
状态提升
状态提升就是将各个子组件的 公共state
提升到它们的父组件进行统一存储、处理(这就是所谓的”单一数据源“),负责setState
的函数传到下边的子级组件,然后再将父组件处理后的数据或函数props
到各子组件中。
下面的例子是将状态info
提升到父组件中进行管理
1.<FilmItem>
组件调用父组件传来的回调函数传递synopsis
的值
2.父组件通过setState
设置info
的值
3.父组件将info
通过props
传递给子组件<FilmDetail >
import React, { Component } from 'react'
export default class App extends Component {
constructor(){
super()
this.state = {
filmList:[{
name:"唐人街探案",
poster:"http://img.menglinfeng.top/img/2.png",
grade:"5",
synopsis:"秦风(刘昊然饰)接到唐仁(王宝强饰)的邀请来纽约参加其与阿香的婚礼。豪气逼人的唐仁迎接秦风,极尽招摇,岂料婚礼其... "
}],
info:""
}
}
render() {
return (
<div>
{/* {this.state.info} */}
{
this.state.filmList.map(item=>
<FilmItem key={item.filmId} {...item} onEvent={(value)=>{
this.setState({
info:value
})
}}></FilmItem>
)
}
<FilmDetail info={this.state.info}></FilmDetail>
</div>
)
}
}
/*受控组件*/
class FilmItem extends Component{
render(){
// console.log(this.props)
let {name, poster,grade,synopsis} = this.props
return <div className="filmitem" onClick={()=>{
this.props.onEvent(synopsis)
}}>
<img src={poster} alt={name}/>
<h4>{name}</h4>
<div>观众评分:{grade}</div>
</div>
}
}
class FilmDetail extends Component{
render(){
return <div className="filmdetail">
{this.props.info}
</div>
}
}
发布订阅模式
发布订阅主要用来解决复杂的层集之间的数据交互,比如兄弟之间的复杂传值,这种情况就不适合使用props
和context
来进行传值。
1、下载:npm install pubsub-js --save
;
2、引入:import PubSub from ‘pubsub-js’
;
3、订阅:PubSub.subscribe('name',function(data){ })
;
4、发布:PubSub.publish('name',data)
;
5、取消订阅:PubSub.unsubscribe()
;
import React, { Component } from 'react'
import PubSub from 'pubsub-js'
export default class App extends Component {
render() {
return (
<div>
<Son></Son>
<Child></Child>
</div>
)
}
}
class Son extends Component {
state = {
num: 1
}
handleClick() {
let result = this.state.num
result++
this.setState({
num: result
})
// 调用pubsub提供的方法publish(发布者利用接收到的数据传给订阅者page)
//(plus为发布的函数名,相当于标识身份用的)
PubSub.publish('plus', this.state.num)
}
render() {
return (<div>
Son
<button onClick={() => { this.handleClick() }}>Click</button>
</div>)
}
}
class Child extends Component {
state = {
num: 0
}
componentDidMount() {
// 订阅者接收发布者提供的数据data(pageNumber为发布的函数名,相当于标识身份用的)
PubSub.subscribe('plus', (msg, data) => {
this.setState({
num: data
})
})
}
render() {
return (<div>
{this.state.num}
</div>)
}
}
1.<Child>
组件挂载之后订阅Plus
方法。
2.点击<Son>
组件的Click
按钮发布Plus
方法,传入需要发布的参数。
3.<Child>
组件订阅触发Plus
方法操作获取的data
。