NiceModal:重新思考弹窗在React中的使用方式
时间:2023-03-28 18:45:19
HTML
鍦ㄦ垜浠繘鍏ユ棰樹箣鍓嶏紝璁╂垜浠潵鐪嬬湅涓€浜涗笌寮圭獥鐩稿叧鐨勬湁瓒e満鏅煠斻€備竴浜涙湁瓒g殑鐜板疄鍦烘櫙妗堜緥涓€锛氬叏灞€寮圭獥涓婂浘鏄帢閲戠殑鐧诲綍寮圭獥銆傛湭鐧诲綍鏃惰Е鍙戝脊绐楃殑鏈轰細鏈夊緢澶氾紝渚嬪锛氱偣鍑婚〉鐪夌櫥褰曟寜閽偣鍑绘枃绔犲垪琛ㄩ〉鎴栬鎯呴〉鐐硅禐璇勮鏂囩珷鐑偣銆佽瘎璁虹儹鐐广€佽€屽儚鐑偣...寮€鍙戣€呭線寰€浼氬熀浜庣涓夋柟缁勪欢搴撳畾涔変竴涓?LoginModal/>锛岀劧鍚庢寕杞藉埌Root缁勪欢涓嬶細const[otherLoginData,setOtherLoginData]=useState();//鍏朵粬閫昏緫...return(setVisible(false)}otherLoginData={otherLoginData}/>
);}杩欎細瀵艰嚧涓€浜涢棶棰橈細
鐨勫唴閮ㄩ€昏緫浼氬湪缁勪欢娓叉煋鏃舵墽琛岋紝鍗充娇寮瑰嚭绐楀彛澶勪簬闅愯棌鐘舵€佺殑棰濆澶嶆潅鎬с€傜敱浜庢湁澶氫釜瑙﹀彂鏈轰細锛宻etVisible鍜宻etOtherLoginData闇€瑕侀€忎紶缁?Main/>鍐呴儴鐨勫涓瓙缁勪欢銆備綘鍙互閫夋嫨閫氳繃props閫愬眰浼犲叆锛堥鐭ラ亾鏈夊灏戝眰锛侊級锛屼篃鍙互寮曞叆宸ュ叿鐘舵€佸叡浜紝浣嗕笉绠℃€庢牱锛岃繖閮戒笉鏄竴浠跺鏄撶殑浜嬶紱闅忕潃绫讳技鐨勫脊绐楄秺鏉ヨ秺澶氾紝鏍圭粍浠朵細缁存姢寰堝寮圭獥缁勪欢鐨勭姸鎬佲€︹€﹀ぉ鐭ラ亾涓轰粈涔堝湪涓€涓枃浠朵腑闇€瑕佸涓脊绐楁墠鑳介噸澶嶆樉绀篔ump銆傛樉绀哄脊鍑虹獥鍙o紝涓轰粈涔堣繖涔堝鏉傦紵涓婇潰鐨勬渚嬫潵鑷簬@ebay/nice-modal-react锛岀◢浣滀慨鏀归櫎浜嗕笂闈㈡彁鍒扮殑鍏ㄥ眬寮圭獥鍦烘櫙澶栵紝杩樻湁涓€涓満鏅篃寰堥夯鐑︺€侰ase2锛氬甫鏈夊垎鏀拰渚濊禆鐨勫脊绐楄鐢ㄦ埛鍜屽紑鍙戣€呭ご鐤笺€傚脊绐?纭寮圭獥2锛屽脊绐?鍙栨秷鏃跺脊鍑恒€傚脊绐?鍜屽脊绐?涔熸湁鐩稿簲鐨勫垎鏀€昏緫锛屽瓙瀛欐弧婊$殑寰堝鏄擄紝浣嗘槸瀹炵幇甯歌鐨勫0鏄庡紡寮圭獥缁勪欢灏卞緢鍚撲汉浜嗭紒涓嶆槸閭d箞閫氱敤鐨勮В鍐虫柟妗堟憜鑴辨墍璋撶殑React鍝插锛氭暟鎹┍鍔ㄨ鍥撅紙view=f(data)锛夛紝鍥炲埌鍘熸潵鐨剋indow.confirm鍜寃indow.alert锛屽緢澶氶棶棰橀兘瑙e喅浜嗭細letmountNode:HTMLDivElement|null=null锛涚櫥褰曟ā寮忋€俿how=(props?:LoginModalProps)=>{if(!mountNode){mountNode=document.createElement('div');document.body.appendChild(mountNode);}//閫氳繃ReactDOM.render鑺傜偣灏嗙粍浠舵覆鏌撳埌鍥哄畾ReactDOM.render(
,mountNode);};LoginModal.hide=()=>{mountNode&&ReactDOM.render(
,mountNode);};LoginModal.destroy=()=>{//閫氳繃ReactDOM.unmountComponentAtNodemountNode鍗歌浇鑺傜偣&&ReactDOM.unmountComponentAtNode(mountNode);};缁忚繃浠ヤ笂浠g爜澶勭悊鍚庯紝鍙互鐩存帴閫氳繃LoginModal.show({otherLoginData})鏄剧ず寮圭獥锛堥殣钘忓拰閿€姣佹槸涓€鏍风殑锛夈€傚浜庢湁渚濊禆鐨勫脊绐楋紝鍙互杩斿洖Promise杩涜閾惧紡璋冪敤銆備娇鐢ㄦ柟娉曞涓嬶紝杩欓噷灏变笉杩囧灞曞紑浜嗐€傚皾璇晎constret1=awaitLoginModal.show({otherLoginData});constret2=awaitOhter1Modal.show();}catch(error){constret3=awaitOther2Modal.show();}鐢变簬绋嬪簭閫氳繃ReactDOM.render灏嗙粍浠舵覆鏌撳埌鏂扮殑鑺傜偣鑴辩浜嗗師鏉ョ殑React涓婁笅鏂囷紝杩欏湪鏌愪簺涓ラ噸渚濊禆Context鐨勫満鏅腑鍙兘浼氬緢楹荤儲銆傚脊绐楀彲鑳芥槸鏈€濂界殑鍋氭硶鏈変竴澶╁湪娴忚github鐨勬椂鍊欏彂鐜颁簡@ebay/nice-modal-react锛屾潵鐪嬬湅ebay鐨勫紑鍙戣€呮槸濡備綍鍦≧eact涓嬫妸寮圭獥鍋氬緱瓒冲濂姐€備粠'antd'鍒涘缓寮瑰嚭绐楀彛import{Modal};浠庘€淍ebay/nice-modal-react鈥濆鍏iceModal锛寋useModal}锛沞xportdefaultNiceModal.create(({name})=>{//浣跨敤閽╁瓙鏉ョ鐞嗘ā鎬佺姸鎬乧onstmodal=useModal();return(
modal.hide()}visible={modal.visible}onCancel={()=>modal.hide()}afterClose={()=>modal.remove()}>浣犲ソ{name}锛?/Modal>);});鍜屽熀浜巃ntd鑷畾涔変竴涓脊绐楃粍浠堕潪甯哥浉浼硷紝鍙槸寮圭獥鏄剧ず鐨勯殣寮忕浉鍏硃rops锛堝visible/hide/remove锛夋槸閫氳繃useModal鑾峰彇鐨勶紝鏈€澶栧眰閫氳繃NiceModal灏佽浜嗚缁勪欢.create锛堥珮闃剁粍浠讹級銆備娇鐢ㄥ脊绐椾箣鍓嶏紝闇€瑕佸紩鍏?NiceModal.Provider/>importNiceModalfrom'@ebay/nice-modal-react';ReactDOM.render(,document.getElementById('root'),;鐒跺悗灏卞彲浠ラ€氳繃NiceModal.showanywhere鏉ユ樉绀轰箣鍓嶈嚜瀹氫箟鐨勫脊绐椾簡锛歩mportNiceModalfrom'@ebay/nice-modal-react';浠?./my-antd-modal'瀵煎叆MyAntdModal锛?/鐢变笂闈㈢殑浠g爜鍑芥暟鍒涘缓App(){constshowAntdModal=()=>{//鏄剧ず涓€涓ā鎬侊紝鍏朵腑鐨勫弬鏁颁綔涓洪亾鍏蜂紶閫掔粰缁勪欢NiceModal銆俿how(MyAntdModal,{name:'Nate'})};杩斿洖(div>);}浠ヤ笂鎸囧崡鍙傝€僋iceModal瀹樻柟鏂囨。锛岀敱NiceModal鎵撳寘銆傚ソ澶勬槸鏄捐€屾槗瑙佺殑锛氳皟鐢ㄨ繃绋嬪共鍑€浼橀泤銆傜粍浠朵粛鐒跺瓨鍦ㄤ簬涓婁笅鏂囦腑锛堜綘鍙互鑷畾涔変綅缃紝榛樿鍦≒rovider涓嬶級鏄剧ず/hide鏂规硶鐨勮繑鍥炲€间负Promise锛屾柟渚块摼寮忚皟鐢紙閫氳繃useModal().resolve(val)绛夋柟娉曟敼鍙楶romise鐘舵€侊級銆傜畝鍗曠殑瀹炵幇鎬濊矾濡傛灉浣犲NiceModal鐨勫疄鐜板師鐞嗘劅鍏磋叮锛屽彲浠ユ兂鎯虫垜浠箣鍓嶇殑鐥涚偣銆備粈涔堬紵妗堜緥涓€鎻忚堪浜嗕袱涓富瑕佺棝鐐癸細鏍圭粍浠舵覆鏌撳脊绐楋紝缁存姢寮圭獥鐘舵€佽繃澶氣€斺€擭iceModal寮圭獥缁熶竴娓叉煋銆侫PI锛坰how/hide/useModal锛夋毚闇蹭簡Case2鐨勯摼寮忚皟鐢紝鑴辩浜嗗0鏄庡紡缁勪欢鍚庡彉寰楅潪甯哥畝鍗曪紝鐢ㄥソPromise鍗冲彲constProvider:React.FC=({children})=>{//鍒濆寮瑰嚭淇℃伅const[modals,_dispatch]=useReducer(reducer,initialState);璋冨害=_璋冨害锛涜繑鍥?{children});};constNiceModalPlaceholder:React.FC=()=>{constmodals=useContext(NiceModalContext);//鏍规嵁寮圭獥淇℃伅ID鎵惧埌闇€瑕佹覆鏌撶殑寮圭獥锛圢iceModal.show鏃舵洿鏂帮級constvisibleModalIds=Object.keys(modals).filter((id)=>Boolean(modals[id]));//鎵惧埌瀵瑰簲鍒涘缓鐨勯珮闃剁粍浠讹紙鍦∟iceModal.show鏃舵敞鍐岋級consttoRender=visibleModalIds.filter((id)=>MODAL_REGISTRY[id]).map((id)=>({id,...MODAL_REGISTRY[ID]锛寎锛夛級;return(<>{toRender.map((t)=>({/*娓叉煋NiceModal.create鍒涘缓鐨勯珮闃剁粍浠跺苟娉ㄥ叆ID*/}))}>);};constcreate=>(Comp:React.ComponentType):React.FC
=>({id})=>{constmodals=useContext(NiceModalContext);constshouldMount=Boolean(modals[id]);濡傛灉锛堬紒shouldMount锛墈杩斿洖绌猴紱}return({/*鎵惧埌ID瀵瑰簲鐨勫弬鏁帮紝浼犲叆鍐呴儴鐪熷疄缁勪欢*/});};浜嗚В浜嗕互涓婁笁涓柟娉曞悗锛宻how/hide/useModal绛夋柟娉曢兘鏄熀浜巇ispatch鍑芥暟鏇存柊寮圭獥鏁版嵁锛圕ontext锛夋潵瑙﹀彂瑙嗗浘鏇存柊锛坰how鏂规硶澶氫簡涓€姝ユ敞鍐岋紝鐢熸垚ID鍜宐indtothecorrespondinghigh-levelcomponent)鎺ㄨ崘闃呰eBay/nice-modal-react:AmodalstatemanagerforReact.Modal.confirmviolatesReact'smode?