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.jsximport Popup from './Popup';const App = () => { return ( <> ... <Popup /> </> );};
使用全局变量控制。
// 显示$popup.show();// 隐藏$popup.hide();
到此,关于“React Native Popup怎么实现”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341