React?Native?Popup怎么實現
這篇文章主要介紹“React?Native?Popup怎么實現”,在日常操作中,相信很多人在React?Native?Popup怎么實現問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”React?Native?Popup怎么實現”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
React Native 官方提供了 Modal
組件,但 Modal
是屬于全屏的彈出層,當 Modal
顯示時,操作區域只有 Modal
里的元素,而且焦點會被 Modal
劫持。雖然移動端不常見,但有些場景還是希望可以用輕量級一點的 Popup
。
在 React Native 里,元素的層級是不可以被穿透的,子元素無論如何都不能遮擋父元素。所以選擇了在頂層添加 Popup
,設置絕對定位,顯示時根據指定元素來動態調整 Popup
的位置的方案。
具體實現
Popup
會有顯示或隱藏兩種狀態,使用一個 state
來控制。
const?Component?=?()?=>?{ ??const?[visible,?setVisible]?=?useState(false); ?? ??return?( ????<> ??????{visible?&&?<></>} ????</> ??); };
Popup
的 屬于視圖類組件,UI 結構包括:
一個作為容器的
View
,由于 iOS 有劉海,所以在 iOS 上需要使用SafeAreaView
來避免被劉海遮擋。同時添加一個點擊事件監聽當點擊時關閉Popup
。一個指向目標對象的三角形。
一個包裹內容的
View
。
由于 Popup
的位置和內容是動態的,所以需要兩個 state
存儲相關數據。
一個存儲位置相關的 CSS。
一個存儲動態內容。
const?Component?=?({?style,?...other?})?=>?{ ??const?[visible,?setVisible]?=?useState(false); ??const?[popupStyle,?setPopupStyle]?=?useState({}); ??const?[content,?setContent]?=?useState(null); ?? ??const?onPress?=?useCallback(()?=>?{ ????setVisible(false); ??},?[]); ?? ??return?( ????<> ??????{visible?&& ????????createElement( ??????????Platform.OS?===?'ios'???SafeAreaView?:?View, ??????????{ ????????????style:?{ ??????????????...styles.popup, ??????????????...popupStyle, ????????????}, ??????????}, ??????????<TouchableOpacity?onPress={onPress}> ????????????<View?style={styles.triangle}?/> ????????????<View?style={{?...styles.content,?...style?}}?{...other}> ??????????????{content} ????????????</View> ??????????</TouchableOpacity>, ????????)} ????</> ??); }; const?styles?=?StyleSheet.create({ ??popup:?{ ????position:?'absolute', ????zIndex:?99, ????shadowColor:?'#333', ????shadowOpacity:?0.12, ????shadowOffset:?{?width:?2?}, ????borderRadius:?4, ??}, ??triangle:?{ ????width:?0, ????height:?0, ????marginLeft:?12, ????borderLeftWidth:?8, ????borderLeftColor:?'transparent', ????borderRightWidth:?8, ????borderRightColor:?'transparent', ????borderBottomWidth:?8, ????borderBottomColor:?'white', ??}, ??content:?{ ????backgroundColor:?'white', ??}, });
因為是全局的 Popup
,所以選擇了一個全局變量來提供 Popup
相關的操作方法。
如果全局 Popup
不適用,可以改成在需要時插入 Popup
并使用 ref
來提供操作方法。
目標元素,動態內容和一些相關的可選配置都是在調用 show
方法時通過參數傳入的,
useEffect(()?=>?{ ??global.$popup?=?{ ????show:?(triggerRef,?render,?options?=?{})?=>?{ ??????const?{?x:?offsetX?=?0,?y:?offsetY?=?0?}?=?options.offset?||?{}; ??????triggerRef.current.measure((x,?y,?width,?height,?left,?top)?=>?{ ????????setPopupStyle({ ??????????top:?top?+?height?+?offsetY, ??????????left:?left?+?offsetX, ????????}); ????????setContent(render()); ????????setVisible(true); ??????}); ????}, ????hide:?()?=>?{ ??????setVisible(false); ????}, ??}; },?[]);
完整代碼
import?React,?{ ??createElement, ??forwardRef, ??useState, ??useEffect, ??useCallback, }?from?'react'; import?PropTypes?from?'prop-types'; import?{ ??View, ??SafeAreaView, ??Platform, ??TouchableOpacity, ??StyleSheet, }?from?'react-native'; const?Component?=?({?style,?...other?},?ref)?=>?{ ??const?[visible,?setVisible]?=?useState(false); ??const?[popupStyle,?setPopupStyle]?=?useState({}); ??const?[content,?setContent]?=?useState(null); ??const?onPress?=?useCallback(()?=>?{ ????setVisible(false); ??},?[]); ??useEffect(()?=>?{ ????global.$popup?=?{ ??????show:?(triggerRef,?render,?options?=?{})?=>?{ ????????const?{?x:?offsetX?=?0,?y:?offsetY?=?0?}?=?options.offset?||?{}; ????????triggerRef.current.measure((x,?y,?width,?height,?left,?top)?=>?{ ??????????setPopupStyle({ ????????????top:?top?+?height?+?offsetY, ????????????left:?left?+?offsetX, ??????????}); ??????????setContent(render()); ??????????setVisible(true); ????????}); ??????}, ??????hide:?()?=>?{ ????????setVisible(false); ??????}, ????}; ??},?[]); ??return?( ????<> ??????{visible?&& ????????createElement( ??????????Platform.OS?===?'ios'???SafeAreaView?:?View, ??????????{ ????????????style:?{ ??????????????...styles.popup, ??????????????...popupStyle, ????????????}, ??????????}, ??????????<TouchableOpacity?onPress={onPress}> ????????????<View?style={styles.triangle}?/> ????????????<View?style={{?...styles.content,?...style?}}?{...other}> ??????????????{content} ????????????</View> ??????????</TouchableOpacity>, ????????)} ????</> ??); }; Component.displayName?=?'Popup'; Component.prototype?=?{}; const?styles?=?StyleSheet.create({ ??popup:?{ ????position:?'absolute', ????zIndex:?99, ????shadowColor:?'#333', ????shadowOpacity:?0.12, ????shadowOffset:?{?width:?2?}, ????borderRadius:?4, ??}, ??triangle:?{ ????width:?0, ????height:?0, ????marginLeft:?12, ????borderLeftWidth:?8, ????borderLeftColor:?'transparent', ????borderRightWidth:?8, ????borderRightColor:?'transparent', ????borderBottomWidth:?8, ????borderBottomColor:?'white', ??}, ??content:?{ ????backgroundColor:?'white', ??}, }); export?default?forwardRef(Component);
使用方法
-
在入口文件頁面內容的末尾插入
Popup
元素。//?App.jsx import?Popup?from?'./Popup'; const?App?=?()?=>?{ ??return?( ????<> ??????... ??????<Popup?/> ????</> ??); };
-
使用全局變量控制。
//?顯示 $popup.show(); //?隱藏 $popup.hide();
到此,關于“React?Native?Popup怎么實現”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注蝸牛博客網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:niceseo99@gmail.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。
評論