期刊介绍
期刊导读
- 08/17各种无线通信技术在车联网中有什么应用
- 08/1730分钟精通十种React组件之间通信的方法
- 08/17深圳华强王瑛:信息通信企业向产业链高端演进
- 08/17院士专家热议新一代信息通信产业发展
- 08/17承德市人民政府与中国信息通信研究院签署战略
30分钟精通十种React组件之间通信的方法(3)
const Parent = () => { const [coords, setCoords] = useState({}); return Awesome content that is never cut off by its parent container! }
这样就ok啦,虽然父组件仍然是overflow: hidden,但我们的Tooltip再也不会被截断了,因为它直接超脱了,它渲染到body节点下的里去了。
总结下适用的场景: Tooltip、Modal、Popup、Dropdown等等
8. Global Variables
哈哈,这也不失为一个可行的办法啊。当然你最好别用这种方法。
class ComponentA extends { handleClick = () => window.a = 'test' ...}class ComponentB extends { render() { return {window.a}}}
9. Observer Pattern
观察者模式是软件设计模式里很常见的一种,它提供了一个订阅模型,假如一个对象订阅了某个事件,当那个事件发生的时候,这个对象将收到通知。
这种模式对于我们前端开发者来说是最不陌生的了,因为我们经常会给某些元素添加绑定事件,会写很多的event handlers,比如给某个元素添加一个点击的响应事件('click', handleClickEvent),每当elm元素被点击时,这个点击事件会通知elm元素,然后我们的回调函数handleClickEvent会被执行。这个过程其实就是一个观察者模式的实现过程。
那这种模式跟我们讨论的react组件通信有什么关系呢?当我们有两个完全不相关的组件想要通信时,就可以利用这种模式,其中一个组件负责订阅某个消息,而另一个元素则负责发送这个消息。javascript提供了现成的api来发送自定义事件: CustomEvent,我们可以直接利用起来。
首先,在ComponentA中,我们负责接受这个自定义事件:
class ComponentA extends { componentDidMount() { ('myEvent', ) } componentWillUnmount() { ('myEvent', ) } handleEvent = (e) => { () //i'm zach }}
然后,ComponentB中,负责在合适的时候发送该自定义事件:
class ComponentB extends { sendEvent = () => { (new CustomEvent('myEvent', { detail: { log: \"i'm zach\" } })) } render() { return }}
这样我们就用观察者模式实现了两个不相关组件之间的通信。当然现在的实现有个小问题,我们的事件都绑定在了document上,这样实现起来方便,但很容易导致一些冲突的出现,所以我们可以小小的改良下,独立一个小模块EventBus专门这件事:
class EventBus { constructor() { this.bus = ('fakeelement'); } addEventListener(event, callback) { (event, callback); } removeEventListener(event, callback) { (event, callback); } dispatchEvent(event, detail = {}){ (new CustomEvent(event, { detail })); }}export default new EventBus
然后我们就可以愉快的使用它了,这样就避免了把所有事件都绑定在document上的问题:
import EventBus from './EventBus'class ComponentA extends { componentDidMount() { ('myEvent', ) } componentWillUnmount() { ('myEvent', ) } handleEvent = (e) => { () //i'm zach }}class ComponentB extends { sendEvent = () => { ('myEvent', {log: \"i'm zach\"})) } render() { return }}
最后我们也可以不依赖浏览器提供的api,手动实现一个观察者模式,或者叫pub/sub,或者就叫EventBus。
function EventBus() { const subscriptions = {}; = (eventType, callback) => { const id = Symbol('id'); if (!subscriptions[eventType]) subscriptions[eventType] = {}; subscriptions[eventType][id] = callback; return { unsubscribe: function unsubscribe() { delete subscriptions[eventType][id]; if ((subscriptions[eventType]).length === 0) { delete subscriptions[eventType]; } }, }; }; = (eventType, arg) => { if (!subscriptions[eventType]) return; (subscriptions[eventType]) .forEach(key => subscriptions[eventType][key](arg)); };}export default EventBus;
10. Redux等
最后终于来到了大家喜闻乐见的Redux等状态管理库,当大家的项目比较大,前面讲的9种方法已经不能很好满足项目需求时,才考虑下使用redux这种状态管理库。这里就先不展开讲解redux了...否则我花这么大力气讲解前面9种方法的意义是什么???
总结
十种方法,每种方法都有对应的适合它的场景,大家在设计自己的组件前,一定要好好考虑清楚采用哪种方式来解决通信问题。
文初提到的那个小问题,最后我采用方案9,因为既然是小迭代项目,又是改别人的代码,当然最好避免对别人的代码进行太大幅度的改造。而pub/sub这种方式就挺小巧精致的,既不需要对别人的代码结构进行大改动,又可以满足产品需求。
文章来源:《信息通信技术与政策》 网址: http://www.xxtxzz.cn/zonghexinwen/2020/0817/599.html