新西兰服务器

React Native Popup怎么实现


React Native Popup怎么实现

发布时间:2022-05-18 13:54:51 来源:高防服务器网 阅读:63 作者:iii 栏目:开发技术

这篇文章主要介绍“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怎么实现”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注高防服务器网网站,小编会继续努力为大家带来更多实用的文章!

[微信提示:高防服务器能助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。

[图文来源于网络,不代表本站立场,如有侵权,请联系高防服务器网删除]
[