创建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);
效果图
其他样式也可以这样写,参考如下