为什么在允许位置权限后不能设置状态值(如果允许位置权限,默认值为当前位置)?
Why can't I set state value (default value is current location if I allow location permission) after I allowed location permission?
我有 select 个城市选项集合。如果我允许,默认 selected 值是当前位置。但是在我允许位置权限后,不能 select 另一个值。所以,我可以 select 另一个城市一秒钟,然后再次设置状态当前城市。
导航地理定位代码:
const useCurrentLocation = () => {
// store location in state
const [location, setLocation] = useState();
// Success handler for geolocation's `getCurrentPosition` method
const handleSuccess = (position) => {
const { latitude, longitude } = position.coords;
setLocation({
latitude,
longitude
});
};
useEffect(() => {
if (!navigator.geolocation) {
return false;
}
// Call the Geolocation API
navigator.geolocation.getCurrentPosition(handleSuccess);
}, []);
// Expose location result
return { location };
};
export default useCurrentLocation;
根据位置坐标查找最近的城市并设置loc代码:
function Nearest({ loc, setLoc }) {
const { location } = useCurrentLocation();
const { city } = useCity();
location && NearestCity(location.latitude, location.longitude);
// Convert Degress to Radians
function Deg2Rad(deg) {
return (deg * Math.PI) / 180;
}
function PythagorasEquirectangular(lat1, lon1, lat2, lon2) {
lat1 = Deg2Rad(lat1);
lat2 = Deg2Rad(lat2);
lon1 = Deg2Rad(lon1);
lon2 = Deg2Rad(lon2);
var R = 6371; // km
var x = (lon2 - lon1) * Math.cos((lat1 + lat2) / 2);
var y = lat2 - lat1;
var d = Math.sqrt(x * x + y * y) * R;
return d;
}
function NearestCity(latitude, longitude) {
var minDif = 99999;
var closest;
var dif;
city.map((item, index) => {
dif = PythagorasEquirectangular(latitude, longitude, item.lat, item.lon);
if (dif < minDif) {
closest = index;
minDif = dif;
}
});
setLoc(city[closest]);
}
//select city
const handleChange = (e) => {
var index = e.target.selectedIndex;
setLoc(city[index]);
};
return select 选项:
<select value={loc.name} onChange={handleChange}>
{city.map((val, i) => (
<option id={i} key={i} value={val.name}>
{val.name} - {i}
</option>
))}
</select>
通过将值设置为您的反应状态,您已将其设为 controlled input。
一个解决方案是从您的 useCurrentLocation
挂钩导出 setLocation
并使用它来代替您的 setLoc
(或者如果您需要 setLoc
则同时调用两者)。
另一种方法是使用 defaultvalue (uncontrolled input)。
我解决了问题!
解决方案是将 NearestCity 放入由位置触发的 useEffect 中。
useEffect(() => {
location && NearestCity(location.latitude, location.longitude);
}, [location]);
我有 select 个城市选项集合。如果我允许,默认 selected 值是当前位置。但是在我允许位置权限后,不能 select 另一个值。所以,我可以 select 另一个城市一秒钟,然后再次设置状态当前城市。
导航地理定位代码:
const useCurrentLocation = () => {
// store location in state
const [location, setLocation] = useState();
// Success handler for geolocation's `getCurrentPosition` method
const handleSuccess = (position) => {
const { latitude, longitude } = position.coords;
setLocation({
latitude,
longitude
});
};
useEffect(() => {
if (!navigator.geolocation) {
return false;
}
// Call the Geolocation API
navigator.geolocation.getCurrentPosition(handleSuccess);
}, []);
// Expose location result
return { location };
};
export default useCurrentLocation;
根据位置坐标查找最近的城市并设置loc代码:
function Nearest({ loc, setLoc }) {
const { location } = useCurrentLocation();
const { city } = useCity();
location && NearestCity(location.latitude, location.longitude);
// Convert Degress to Radians
function Deg2Rad(deg) {
return (deg * Math.PI) / 180;
}
function PythagorasEquirectangular(lat1, lon1, lat2, lon2) {
lat1 = Deg2Rad(lat1);
lat2 = Deg2Rad(lat2);
lon1 = Deg2Rad(lon1);
lon2 = Deg2Rad(lon2);
var R = 6371; // km
var x = (lon2 - lon1) * Math.cos((lat1 + lat2) / 2);
var y = lat2 - lat1;
var d = Math.sqrt(x * x + y * y) * R;
return d;
}
function NearestCity(latitude, longitude) {
var minDif = 99999;
var closest;
var dif;
city.map((item, index) => {
dif = PythagorasEquirectangular(latitude, longitude, item.lat, item.lon);
if (dif < minDif) {
closest = index;
minDif = dif;
}
});
setLoc(city[closest]);
}
//select city
const handleChange = (e) => {
var index = e.target.selectedIndex;
setLoc(city[index]);
};
return select 选项:
<select value={loc.name} onChange={handleChange}>
{city.map((val, i) => (
<option id={i} key={i} value={val.name}>
{val.name} - {i}
</option>
))}
</select>
通过将值设置为您的反应状态,您已将其设为 controlled input。
一个解决方案是从您的 useCurrentLocation
挂钩导出 setLocation
并使用它来代替您的 setLoc
(或者如果您需要 setLoc
则同时调用两者)。
另一种方法是使用 defaultvalue (uncontrolled input)。
我解决了问题!
解决方案是将 NearestCity 放入由位置触发的 useEffect 中。
useEffect(() => {
location && NearestCity(location.latitude, location.longitude);
}, [location]);