为什么在允许位置权限后不能设置状态值(如果允许位置权限,默认值为当前位置)?

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]);