高德地图定位模块
// hookimport { useState, useEffect, useCallback } from 'react';import { Platform } from 'react-native';import { Geolocation, setLocatingWithReGeocode, stop } from 'react-native-amap-geolocation';import { check, request, PERMISSIONS, RESULTS } from 'react-native-permissions';import { Toast } from '@/components';// 吐司组件const isAndroid = Platform.OS === 'android';const permissionType =Platform.OS === 'ios'? PERMISSIONS.IOS.LOCATION_WHEN_IN_USE: PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION;function useAmapLocation(initLocation) {const [location, setLocation] = useState(initLocation);const [err, setErr] = useState();useEffect(() => {setTimeout(() => {checkPermissions();}, 1000);return () => {stop();};}, []);const handleLocationSuccess = ({ location: _location }) => {if (_location) {setLocation(_location);}};const handleLocationError = (e) => {setErr({ message: '', e });};const getGeolocation = async () => {if (!isAndroid) {setLocatingWithReGeocode(true);}Geolocation.getCurrentPosition(handleLocationSuccess, handleLocationError);};const checkPermissions = useCallback(() => {check(permissionType).then((result) => {switch (result) {case RESULTS.UNAVAILABLE:Toast.showError('当前设备没有位置服务');break;case RESULTS.DENIED:requestPermissions();break;case RESULTS.GRANTED:getGeolocation();break;case RESULTS.BLOCKED:Toast.showError('您设定永不授权,请自行前往设置开启');break;default:break;}}).catch(() => {});// eslint-disable-next-line react-hooks/exhaustive-deps}, []);const requestPermissions = () => {request(permissionType).then((result) => {if (result === RESULTS.GRANTED) {getGeolocation();} else {setErr({ message: '没有定位权限' });}}).catch(() => {});};return { location, err };}export default useAmapLocation;
高德地图组件
@react-native-community/masked-view
react-native-linear-gradient
import React from 'react';import { StyleSheet } from 'react-native';import MaskedView from '@react-native-community/masked-view';import LinearGradient from 'react-native-linear-gradient';function GradientText({ children, style, ...restProps }) {return (<MaskedView style={style} maskElement={children}>{/* Shows behind the mask, you can put anything here, such as an image */}<LinearGradientstart={start}end={end}colors={colors}style={[StyleSheet.absoluteFill]}{...restProps}/></MaskedView>);}
<GradientText colors={['black','white]}><Text>渐变文字</Text></GradientText>
import React, { useMemo } from 'react';import PropTypes from 'prop-types';import { View } from 'react-native';function getBorderStyles({ direction, width, height, color }) {if (direction === 'up') {return {borderTopWidth: 0,borderRightWidth: width / 2.0,borderBottomWidth: height,borderLeftWidth: width / 2.0,borderTopColor: 'transparent',borderRightColor: 'transparent',borderBottomColor: color,borderLeftColor: 'transparent',};} else if (direction === 'right') {return {borderTopWidth: height / 2.0,borderRightWidth: 0,borderBottomWidth: height / 2.0,borderLeftWidth: width,borderTopColor: 'transparent',borderRightColor: 'transparent',borderBottomColor: 'transparent',borderLeftColor: color,};} else if (direction === 'down') {return {borderTopWidth: height,borderRightWidth: width / 2.0,borderBottomWidth: 0,borderLeftWidth: width / 2.0,borderTopColor: color,borderRightColor: 'transparent',borderBottomColor: 'transparent',borderLeftColor: 'transparent',};} else if (direction === 'left') {return {borderTopWidth: height / 2.0,borderRightWidth: width,borderBottomWidth: height / 2.0,borderLeftWidth: 0,borderTopColor: 'transparent',borderRightColor: color,borderBottomColor: 'transparent',borderLeftColor: 'transparent',};} else if (direction === 'up-left') {return {borderTopWidth: height,borderRightWidth: width,borderBottomWidth: 0,borderLeftWidth: 0,borderTopColor: color,borderRightColor: 'transparent',borderBottomColor: 'transparent',borderLeftColor: 'transparent',};} else if (direction === 'up-right') {return {borderTopWidth: 0,borderRightWidth: width,borderBottomWidth: height,borderLeftWidth: 0,borderTopColor: 'transparent',borderRightColor: color,borderBottomColor: 'transparent',borderLeftColor: 'transparent',};} else if (direction === 'down-left') {return {borderTopWidth: height,borderRightWidth: 0,borderBottomWidth: 0,borderLeftWidth: width,borderTopColor: 'transparent',borderRightColor: 'transparent',borderBottomColor: 'transparent',borderLeftColor: color,};} else if (direction === 'down-right') {return {borderTopWidth: 0,borderRightWidth: 0,borderBottomWidth: height,borderLeftWidth: width,borderTopColor: 'transparent',borderRightColor: 'transparent',borderBottomColor: color,borderLeftColor: 'transparent',};} else {console.error('Triangle.js wrong direction. ' +direction +' is invalid. Must be one of: ' +['up', 'right', 'down', 'left', 'up-right', 'up-left', 'down-right', 'down-left']);return {};}}function Triangle({ direction, width, height, color, style }) {const borderStyles = getBorderStyles({ direction, width, height, color })return <View style={[{ width:0,height:0,backgroundColor:'transparent',borderStyle:'solid' }, borderStyles, style]} />;}Triangle.defaultProps = {width: 30,height: 30,color: 'black',direction: 'up',};Triangle.propTypes = {width: PropTypes.number,height: PropTypes.number,color: PropTypes.string,direction: PropTypes.oneOf(['up','down','left','right','up-left','up-right','down-left','down-right',]),};export default Triangle;
import { useState, useEffect, useCallback } from 'react'import RNAliyunOSS from 'aliyun-oss-react-native'import { Toast } from '@/components'const getToken = () => {return { stsToken: '', accessKeyId: '', accessKeySecret: '', endPointPath: '' }} // 获取token的APIconst FILE_PREFIX = 'test' // 目录function useAliyunOss() {const [ossToken, setOssToken] = useState()const [instance, setInstance] = useState()useEffect(() => {fetchToken()}, [])useEffect(() => {if (ossToken) {initAliOss()}}, [ossToken, initAliOss])const fetchToken = () => {return getToken().then((res) => {setOssToken(res)return res})}const initAliOss = useCallback(async () => {const { stsToken, accessKeyId, accessKeySecret, endPointPath } = ossToken || {}try {const configuration = {maxRetryCount: 3,timeoutIntervalForRequest: 30,timeoutIntervalForResource: 24 * 60 * 60,}RNAliyunOSS.enableDevMode()RNAliyunOSS.initWithSecurityToken(stsToken, accessKeyId, accessKeySecret, endPointPath, configuration)setInstance(RNAliyunOSS)} catch (error) {console.log(error)}}, [ossToken])const upload = useCallback(({ path }) => {if (!instance) {Toast.showError('初始化上传组件失败,请稍后重试')fetchToken()return Promise.reject()}const { bucket, endpoint } = ossToken || {}const fileName = path.split(/\#|\?/)[0].split('/').pop().trim()const filePath = `file://${path}`const objectkey = `${FILE_PREFIX}/${fileName}`return instance.asyncUpload(bucket, objectkey, filePath).then((res) => {const newPath = `${endpoint}/${objectkey}`return newPath})},[instance, ossToken])return { AliyunOSS: instance, ossToken, fetchToken, upload }}export default useAliyunOss
function Example() {const { upload } = useAliyunOss()const updateImage = async () => {try {const imagePickerRes = await ImagePicker.openPicker({width: 400,height: 400,cropping: true,cropperToolbarColor: 'white',cropperChooseText: '选择',cropperCancelText: '取消',loadingLabelText: '加载中',})const { path } = imagePickerResconst uploadRes = await upload({ path })console.log(uploadRes)} catch (error) {console.log(error)}}return null}
const RnMapArray = ['navigateTo','navigateBack','switchTab','reLaunch','redirectTo','postMessage','setTitle','setShare',];(function FuncMap(target) {if (!target) {return null;}var Funcobj = {}; // RN映射方法RnMapArray.forEach(function(func) {Funcobj[func] = function(...payload) {const params = {command: func,payload: { ...payload },};target.ReactNativeWebView.postMessage(JSON.stringify(params));};}); // 实例方法Funcobj.getEnv = function(callback) {if (typeof callback !== 'function') {return;}var isRn = localStorage.getItem('isRN');var data = {rn: isRn,};callback(data);}; // 挂载到目标上target.RN = Funcobj;})(window);
根据错误信息定位哪个包有问题,google搜索错误信息关键词,一般会定位到github包下面的issue,因为你犯的错误,很可能别人也碰到了,正好大家在讨论,而且可能还有人给出了解决方案
测试环境,线上环境