RN全局封装一个toast弹窗提示(在任意地方只要调用方法就能使用)

创建Toast.js

let toastInstance = null;

export const showToast = options => {
  if (toastInstance) { // toastInstance有值的话
    toastInstance(options);
  } else {
    console.error('Toast instance is not initialized');
  }
};

export const setToastInstance = instance => {
  toastInstance = instance; // 在ToastProvider.js调用这个方法给toastInstance赋值
};

创建ToastProvider.js组件,内容如下

import React, {createContext, useContext, useState, useCallback, Text} from 'react';
import {Image, StyleSheet, View} from 'react-native';
import Modal from 'react-native-modal'; // 弹窗的model层,这个根据自己项目可以替换自己的样式
import {ActivityIndicator} from 'react-native-paper'; // UI组件库的转圈的动画组件,提示加载中,这个根据自己项目可以替换
import {setToastInstance} from './Toast';  // 这里存放的就是弹窗方法,这个不可替换,固定的

const failIcon = require('../static/image/toast_fail.png'); // 失败的弹窗图片,这个根据自己项目可以替换
const successIcon = require('../static/image/toast_success.png'); // 成功的弹窗图片,这个根据自己项目可以替换

const ToastContext = createContext(); // 全局上下文

export const ToastProvider = ({children}) => {
  const [toast, setToast] = useState({
    visible: false,
    message: '',
    type: 'default',
  });

  const showToast = useCallback(({message, type}) => {
    setToast({visible: true, message, type});
    setTimeout(() => {
      setToast({visible: false, message: '', type: 'default'});
    }, 2000);
  }, []);

  // 设置全局实例
  setToastInstance(showToast);

  function getIcon() {
    if (toast.type == 'success') { // 如果类型是成功则返回成功图片,否则就是失败图片
      return successIcon;
    } else {
      return failIcon;
    }
  }

  return (
    <ToastContext.Provider value={{showToast}}>
      {children}
      <Modal
        style={styles.modal}
        isVisible={toast.visible}
        backdropOpacity={0}
        animationIn={'zoomIn'}
        animationOut={'fadeOut'}
        animationInTiming={200}
        animationOutTiming={200}>
        <View style={styles.container}>
          {toast.type !== 'loading' && (
            <Image source={getIcon()} style={styles.icon} />
          )}
          {toast.type === 'loading' && (
            <ActivityIndicator animating={true} size={30} color="white" />
          )}
          <Text
            fontWeight={'bold'}
            style={styles.textS}
            numberOfLines={2}
            ellipsizeMode="tail">
            {toast.message}  // 弹窗提示内容
          </Text>
        </View>
      </Modal>
    </ToastContext.Provider>
  );
};

const styles = StyleSheet.create({
  modal: {
    justifyContent: 'center',
    alignItems: 'center',
    margin: 0,
  },
  container: {
    height: 120,
    width: 120,
    backgroundColor: 'rgba(0,0,0,0.7)',
    borderRadius: 15,
    alignItems: 'center',
    justifyContent: 'center',
  },
  icon: {
    width: 40,
    height: 40,
    marginBottom: 10,
  },
  textS: {
    fontSize: 15,
    color: '#FFF',
    marginTop: 10,
    textAlign: 'center',
    marginHorizontal: 10,
  },
});

在根目录下index.js加入以下内容

/**
 * @format
 */

import {AppRegistry, LogBox} from 'react-native';
import App from './App';
import {name as appName} from './app.json';
import {PaperProvider} from 'react-native-paper';
import {ToastProvider} from './src/components/ToastProvider'; // 引入ToastProvider组件
LogBox.ignoreAllLogs(true);
export default function Main() {
  return (
    <PaperProvider>
      <ToastProvider> // 将其进行全局包裹整个页面
        <App />
      </ToastProvider>
    </PaperProvider>
  );
}

AppRegistry.registerComponent(appName, () => Main);

至此封装结束

使用方法

例如我要封装全局的axios请求,在请求到code为0时弹出失败信息,则可以按照如下调用方法

import axios from 'axios';
import {showToast} from '../components/Toast'; // 引入toast.js里面的方法
const instace = axios.create({
  baseURL: 'https://internal.takehr.cn',
  timeout: 5000,
});
//配置请求拦截器,在请求之前的数据处理,比如在请求头添加token,所有的请求都会经过拦截器
instace.interceptors.request.use(
  async config => {
    con = {};
    try {
      return config;
    } catch (error) {
      return Promise.reject(error);
    }
  },
  err => {
    return Promise.reject(err);
  },
);

// 响应拦截器:在请求响应之后对数据处理,比如:登录失败、请求数据失败的处理
instace.interceptors.response.use(
  response => {
    if (response.data.code == 0) {
        // 在这里进行Toast调用
    	showToast({message: 'test', type: 'success'});
    }
    return response; 
  },
  err => {
    return Promise.reject(err);
  },
);

//封装请求的api
const callapi = (method = 'GET', url, data = {}, customHeaders = {}) => {
  if (method === 'GET') {
    return instace({
      method,
      url,
      params: data,
      ...customHeaders,
    });
  } else {
    return instace({
      method,
      url,
      params: {},
      data: data,
      ...customHeaders,
    });
  }
};
//封装GET,POST请求函数
export const getapi = (url, data, customHeaders) =>
  callapi('GET', url, data, customHeaders);
export const postapi = (url, data, customHeaders) =>
  callapi('POST', url, data, customHeaders);

效果图

在这里插入图片描述
其他样式也可以这样写,参考如下

在这里插入图片描述

  • 6
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

萧寂173

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值