我的 React Native 应用程序中有一个功能组件,加载时我想检查用户位置权限,然后根据用户位置加载地图。加载该位置后,我会调用 Google 地图 API 来搜索附近的商店并在
MapView
中显示标记。
问题是,地图渲染时正在进行 API 调用,但在地图稍微移动之前不会显示任何标记。从我的
console.logs
来看,当视图首次加载时,API 调用正在执行,我确实看到结果返回并设置为状态对象。
我的代码如下,我对 React-Native 比较陌生,欢迎任何输入!
import React, { useState, useEffect, useCallback } from 'react';
import { View, Platform, StyleSheet } from 'react-native';
import Geolocation from 'react-native-geolocation-service';
import MapView, { Marker, Region } from 'react-native-maps';
import { request, PERMISSIONS } from 'react-native-permissions';
import debounce from 'lodash.debounce';
interface StoreFinderState {
latitude: number;
longitude: number;
latitudeDelta: number;
longitudeDelta: number;
}
const StoreFinderView: React.FC = () => {
const [mapRegion, setMapRegion] = useState<StoreFinderState>({
// Start with default location
latitude: 41.88015,
longitude: -87.63515,
latitudeDelta: 0.05,
longitudeDelta: 0.05,
});
const [stores, setStores] = useState<any[]>([]);
const getLocation = useCallback(() => {
Geolocation.getCurrentPosition(
position => {
console.log(position);
setMapRegion({
latitude: position.coords.latitude,
longitude: position.coords.longitude,
latitudeDelta: 0.05,
longitudeDelta: 0.05,
});
},
error => {
console.log(error.code, error.message);
},
{ enableHighAccuracy: true, timeout: 15000, maximumAge: 10000 }
);
}, []);
useEffect(() => {
const requestLocationPermission = async () => {
const status = await request(
Platform.OS === 'ios' ? PERMISSIONS.IOS.LOCATION_WHEN_IN_USE : PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION
);
if (status === 'granted') {
getLocation();
}
};
requestLocationPermission();
}, []);
useEffect(() => {
searchStores(mapRegion);
}, [mapRegion]);
const searchStores = useCallback(
debounce(async (region: Region) => {
try {
console.log('Search for stores');
const response = await fetch(
'https://maps.googleapis.com/maps/api/place/nearbysearch/json?' +
`keyword=KEYWORD_SEARCH&location=${region.latitude}%2C${region.longitude}&radius=1500` +
'&type=store&key=API_KEY',
{
method: 'GET',
}
);
const data = await response.json();
console.log(data.results.length);
setStores(data.results);
} catch (error) {
console.log(error);
}
}, 500),
[]
);
return (
<View style={styles.container}>
<MapView
style={styles.container}
region={mapRegion}
onRegionChangeComplete={(region) => {setMapRegion(region)}}
>
{stores.map((store: any) => (
<Marker
key={store.place_id}
coordinate={{
latitude: store.geometry.location.lat,
longitude: store.geometry.location.lng,
}}
title={store.name}
description={store.vicinity}
/>
))}
</MapView>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
},
});
export default StoreFinderView;
也许与 useEffects 有关?您是否尝试过将mapRegion传递给负责获取用户许可的useEffect?
我有类似的功能,但我只是传递我想在地图上向用户显示的区域的参数。这是代码,也许你可以从中得到一些东西。
Map.tsx
import React from 'react';
import { View, Text } from 'react-native';
import MapView, { Marker, Region } from 'react-native-maps';
import pinIcon from '../assets/icons/pinicon.png';
// Define the expected type for postLocation prop
type PostLocation = {
latitude: number;
longitude: number;
};
const Map = ({ postLocation }: { postLocation: PostLocation }) => {
const { latitude, longitude } = postLocation;
if (!latitude || !longitude) {
return (
<View style={{ justifyContent: 'center', alignItems: 'center', width: '100%', height: '100%' }}>
<Text>Location data not available.</Text>
</View>
);
}
const region: Region = {
latitude: latitude,
longitude: longitude,
latitudeDelta: 0.01,
longitudeDelta: 0.01,
};
return (
<MapView
style={{ width: '100%', height: '100%' }}
region={region} // Use region to dynamically update the map
showsUserLocation={false}
>
<Marker
coordinate={{ latitude, longitude }}
title="Animal Location"
image={pinIcon}
/>
</MapView>
);
};
export default Map;
MapViewScreen.js
const { postData } = useLocalSearchParams();
const post = JSON.parse(postData); // Parse post data from string
// Define post location with latitude and longitude parsed as numbers
const postLocation = {
latitude: parseFloat(post.latitude),
longitude: parseFloat(post.longitude),
};
<Map postLocation={postLocation} />
另外,只是大声思考,直到找到合适的解决方案,如果稍微移动地图会使其刷新,也许您可以让它稍微移动,例如在渲染后 0,0001 纬度,因此用户看不到它,但是它会刷新标记吗?祝你好运