当前位置: 首页 > Web前端 > HTML

优雅使用React中useEventEmitter实现多组件事件共享

时间:2023-03-29 12:16:39 HTML

馃實鑳屾櫙鍦ㄥ墠绔」鐩笟鍔′腑锛岀粍浠朵箣闂寸殑閫氫俊闈炲父棰戠箒銆傜埗浜蹭紶缁欏効瀛愶紝鍎垮瓙浼犵粰鐖朵翰锛屽厔寮熶紶缁欏厔寮燂紝绛夌瓑銆傚涓粍浠朵箣闂寸殑浜嬩欢閫氱煡鏈夋椂浼氬緢澶寸柤锛屾湁浜咵ventEmitter锛岃繖涓繃绋嬪彲浠ュ彉寰楁洿瀹规槗銆傛湰鐫€鑳界櫧瀚栫粷涓嶈嚜宸卞姩鎵嬬殑鍘熷垯锛岀湅浜嗙湅ahooks锛屽叾涓璾seEventEmitter鍙互鍜屽涓粍浠堕€氫俊銆傚叿浣撳師鐞嗘槸閫氳繃props鎴栬€匔ontext鍏变韩涓€涓叏灞€鐨勭被瀹炰緥锛屼娇鐢ㄥ悗鐨勪綋楠屼笉鏄緢濂姐€傚畠娌℃湁浜嬩欢鍚嶇О锛岄渶瑕佸湪浼犲€煎鎵嬪姩绠$悊浜嬩欢銆?.馃摉鏈熸湜涓庡涓粍浠堕€氫俊锛涙偍鍙互鍙戝嚭浜嬩欢鍚嶇О骞堕€氳繃on鎺ユ敹瀹冿紝绫讳技浜巚ue鐨別ventBus锛涘畠鍙互鍦ㄥ叏鐞冩垨鏈湴鍏变韩锛涴煋℃柊澧瀠seEventEmitter1.1锛宮ain鍑芥暟main鍑芥暟鍒嗕负涓ょ被锛宭ocalsharing閫氳繃鍏ㄥ眬閰嶇疆鏄惁灞炰簬globalsharing锛涘叏灞€鍏变韩鐨勭壒鐐规槸鎵€鏈変娇鐢ㄤ慨楗伴挬瀛愮殑缁勪欢閮藉叿鏈夊叏灞€鍏变韩鐨勮兘鍔涳紝涓嶉渶瑕佸湪椤跺眰浼犻€掍簨浠跺疄渚嬨€傚睘浜庡悓涓€涓疄渚嬶紱鏈湴鍒嗕韩鐨勭壒鐐规槸鎵€鏈夌殑鏈湴鍒嗕韩閮介渶瑕侀€氳繃浜嬩欢瀹炰緥锛屽彲浠ュ垱寤哄涓湰鍦板垎浜疄渚嬨€傚睘浜庡悓涓€绫伙紱鍏ㄥ眬浜嬩欢鍜屽眬閮ㄤ簨浠剁浉浜掔嫭绔嬶紱1.2銆佸師鐞嗗疄鐜板0鏄庝竴涓被锛屽湪绫讳腑瀹氫箟涓€涓猵rivate鐨刴apemit鐩稿綋浜巑ap鐨剆et鎿嶄綔锛宱n鐩稿綋浜巊et鎿嶄綔鑾峰彇浼犲叆鐨勫弬鏁帮紝閫氳繃鐩戝惉鍥炶皟1.3锛岃创涓婃簮鐮侌煈噀vent.jsimport{cloneDeep}from"lodash";typeSubscription=({params,event,}:{params:T;event:string;})=>void;constsubscriptionValueIsArray=(values?:unknown):valuesisany[]=>{returnArray.isArray(values);};classEventEmitter{privatesubscriptions=newMap();鏋勯€犲嚱鏁帮紙锛墈杩欎釜銆傛竻闄わ紙锛?}on=(event:string,listener?:Subscription)=>{if(this.subscriptions.has(event)){constsubscriptionValues=this.璁㈤槄銆傚緱鍒帮紙浜嬩欢锛夛紱if(subscriptionValueIsArray(subscriptionValues))listener?.({params:subscriptionValues?.[0]??[],event:subscriptionValues?.[1]?.event,});}};emit=(event:string|number,...args:Textendsany[]?any[]:any)=>{if(typeofevent==="string"||typeofevent==="number")this.subscriptions.set(event,cloneDeep([args,{event,},])asany,);elsethrownewTypeError("浜嬩欢蹇呴』鏄瓧绗︿覆鎴栨暟瀛?");};removeListener=(event:string)=>{this.subscriptions.delete(event);};clear=()=>{this.subscriptions.clear();};}consteventEmitterOverall=newEventEmitter();export{EventEmitter,eventEmitterOverall};index.tsimport{useEffect,useMemo,useRef}from"react";import{EventEmitter,eventEmitterOverall}from"./event";exportdefaultfunctionuseEventEmitter(options?:{global?:boolean;}){constref=useRef|typeofeventEmitterOverall>();consteventEmitterOptions=useMemo(()=>options??{global:false},[options],);ref.current=useMemo(()=>eventEmitterOptions.global锛?ref.current=eventEmitterOverall):(ref.current=newEventEmitter()),[eventEmitterOptions],);useEffect(()=>{return()=>ref.current?.clear();},[]);returnref.current;}馃敤浣跨敤consteventBus=useEventEmitter({global:true});eventBus?.emit("hello",{name:"react"},{name:"typescript"});eventBus?.on("hello",(value)=>{console.log("hello",value);});