父子组件通信—Props传递数据和方法
父级组件将数据和方法以props形式传递给子组件供子组件使用
import React,{ Component } from "react";import Sub from "./Sub.js";import "./App.css";export default class App extends Component{constructor(props){super(props)this.getCount = this.getCount.bind(this)}getCount(count){console.log(count);}render(){return(<div><Sub title = "今年过节不收礼"getCount = { this.getCount }/></div>)}}
import React,{ Component } from "react";class Sub extends Component{constructor(props){super(props)this.sendCount = this.sendCount.bind(this)}state = { count:0 }sendCount(){//调用父级组件传入的方法this.props.getCount(this.state.count)}return(const props = this.props<div><h1> { props.title } </h1> //从父组件接受props信息展示<button onClick = { this.sendCount }>Click Me //将子组件信息传给父组件供使用</button></div>)}export default Sub;
兄弟组件通信—状态提升
将数据和操作数据的方法,放在兄弟组件共同的父级组件上,也就是状态提升。
跨级组件通信—Context
跨级组件通信,就是父组件向子组件的子组件通信,向更深层的子组件通信。跨级组件通信可以采用下面两种方式:
- 中间组件层层传递 props
- 使用context对象
对于第一种方式,如果父组件结构较深,那么中间的每一层组件都要去传递 props,增加了复杂度,并且这些 props 并不是这些中间组件自己所需要的。
使用 context 是另一种可行的方式,context 相当于一个全局变量,是一个大容器,我们可以把要通信的内容放在这个容器中,这样一来,不管嵌套有多深,都可以随意取用。
import React,{ Component } from "react";import Sub from "./Sub.js";import "./App.css";export default class App extends Component{constructor(props){super(props)this.getCount = this.getCount.bind(this)}// 上级组件声明自己支持 contextstatic childContextTypes = {color:PropTypes.string,getCount:PropTypes.func,}// 父组件提供一个函数,用来返回相应的 context 对象getChildContext(){return{color:"red",getCount:this.getCount.bind(this)}}getCount(count){console.log(count);}render(){return(<div><Sub title = "今年过节不收礼"getCount = { this.getCount }/></div>)}}
import React,{ Component } from "react";class Sub extends Component{constructor(props){super(props)this.sendCount = this.sendCount.bind(this)}// 下级组件声明自己需要使用context 不接收就获取不到context对象static contextTypes = {color:PropTypes.string,getCount:PropTypes.func,}state = { count:0 }sendCount(){//使用context使用接受到的方法this.context.getCount(this.state.count);}return(const props = this.props<div><h1> { props.title } </h1> //从上级组件接受props信息展示<button onClick = { this.sendCount }>Click Me //将下级组件信息传给父组件供使用</button></div>)}export default Sub;
任意组件间通信—PubSub
没有任何包含关系的组件,包括兄弟组件以及不在同一个父级中的非兄弟组件。对于非嵌套组件,可以采用下面两种方式:
- 利用二者共同父组件的 context 对象进行通信
- 使用消息订阅发布机制进行通信
首先,需要在项目引入PubSub库
npm install pubsub-js --save
其次,需要在组件中引入PubSub,并做好消息订阅与发布
import React, { Component } from 'react'import PubSub from 'pubsub-js'class Publish extends Component{constructor(props){super(props)this.sendCount = this.sendCount.bind(this)}state = { count:0 }sendCount(){//发布消息PubSub.publish('sendCount',{isLoading:false,users:response.data.items})}return(const props = this.props<div><h1> { state.xxxx } </h1><button onClick = { this.sendCount }>Click Me //发布消息</button></div>)}export default Publish;
import React, { Component } from 'react'import PubSub from 'pubsub-js'class Subscribe extends Component{constructor(props){super(props)state = { count:0 }this.setCount = this.setCount.bind(this)}setCount(){}componentDidMount(){//订阅消息this.token = PubSub.subscribe('sendCount',(_,stateObj)=>{//回调函数接收两个参数,消息名&&消息内容//必须使用箭头函数或者正确bind this的函数this.setCountthis.setState(stateObj)})}componentWillUnmount(){//组件取消挂载时,取消订阅PubSub.unsubscribe(this.token);}return(const props = this.props<div><h1> { state.count } </h1></div>)}export default Subscribe;
任意组件间通信—集中式状态管理
React中数据通信是单向的,即父组件可以通过props向子组件传递数据,而子组件却不能向父组件传递数据。要实现子组件向父组件传递数据的需求,需要父组件提供一个修改数据的方法,当页面越来越多的时候,数据的管理就会变得异常复杂。
Redux是由Dan Abramov开源的一款前端状态管理框架,Redux将状态管理分为Action、Store和Reducers三部分。其中,Redux将应用程序的状态存储到Store中,组件通过dispatch()方法触发Action,Store接收Action并将Action转发给Reducer,Reducer根据Action类型对状态数据进行处理并将处理结果返回给Store,其他组件通过订阅Store状态的来刷新自身的状态。
如图所示,即为React原理
参考
- https://www.jianshu.com/p/fb915d9c99c4 React组件间通信的几种方式
- https://zhuanlan.zhihu.com/p/89015701 React使用PubSub实现消息订阅发布
- https://github.com/mroderick/PubSubJS PubSub Github仓库地址
- https://www.cxyzjd.com/article/sinat_17775997/82692621 PubSub回调函数bind this
- https://cloud.tencent.com/developer/article/1817831
- https://juejin.cn/post/7031509723190919175 Redux集中式状态管理
- https://segmentfault.com/a/1190000039419540 Redux实践1
