非父子组件通信方式
1)状态提升(中间人模式)
React中的状态提升,就是将多个组件需要共享的状态提升到他们最近的父组件上,在父组件上改变这个状态,然后通过props分发给子组件
2)发布订阅模式实现
订阅者:写回调函数,对接收到参数进行处理
发布者:写执行函数,将参数发布给调度中心
调度中心:管理订阅者和发布者的函数和参数
//调度中心
var bus = {
list:[],
//订阅
subscribe(callback){
this.list.push(callback)//把回调函数加入到list队列中
},
//发布
publish(){
this.list.forEach(callback=>{
callback && callback(info);//触发执行list中所有的回调函数
})
}
}
//订阅者
bus.subscribe((info)=>{
console.log(info)
})
//发布者
bus.publish(info);
3)context状态树传参,即供应商消费者模式,跨组件通信方案
Ⅰ.创建context对象 const GlobalContext = React.createContext()
Ⅱ.给提供通信信息的组件加上供应商标签<GlobalContext.Provider/>,直接将return后的最外层<div></div>套在context标签内部即可,在标签上使用value={{属性或方法}}进行传值
Ⅲ.给需要通信的组件加上消费者标签<GlobalContext.Consumer/>,需要将<div/>放到回调函数内部,回调函数接受value值,在函数内调用value中的方法,修改value中的属性
import axios from 'axios';
import React, { PureComponent } from 'react'
const GlobalContext = React.createContext();//创建context对象
export default class App extends PureComponent {
constructor(){
super();
this.state={
filmdatas:[],
info:""
}
axios({
url:"test.json"
}).then(res=>{
this.setState({
filmdatas:res.data.data.films
})
})
}
render() {
return (
<GlobalContext.Provider value={{
info:this.state.info,
changeInfo:(value)=>{
this.setState({
info:value
})}
}}>
<div>
<LeftShow filmdatas={this.state.filmdatas}></LeftShow>
<RightShow></RightShow>
</div>
</GlobalContext.Provider>
)}
}
class LeftShow extends PureComponent {
render() {
return(
<GlobalContext.Consumer>{
(value)=>{
return(
<div>
{this.props.filmdatas.map(item=>
<ul key={item.filmId} onClick={()=>{
value.changeInfo(item.synopsis)
}}>
<img src={item.poster} alt={item.name}</img>
<li>电影名:{item.name}</li>
<li>上映地:{item.nation}</li>
<li>时长:{item.runtime}分钟</li>
</ul>)
}
</div>)}}
</GlobalContext.Consumer>)
}}
class RightShow extends PureComponent {
render() {
return (
<GlobalContext.Consumer>
{
(value)=><div style={{
width:"200px",
height:"200px",
position:"fixed",
right:"20px",
top:"100px"
}}>
{value.info}
</div>
}
</GlobalContext.Consumer>
)}}