【问题标题】:Passing parameter to custom hook将参数传递给自定义钩子
【发布时间】:2022-01-07 10:28:18
【问题描述】:

有很多关于钩子的文档,但我似乎不太了解它们。

代码

const App = () => {
const [markers, setMarkers] = useState(null);

const fetchMarkers = async () => {
const res = await axios.get(`${process.env.REACT_APP_BASE_URL}/markers`);
setMarkers(res.data);
};

useEffect(() => {
fetchMarkers();
}, []);

useInterval(() => {
fetchMarkers();
}, 10000);
}

我已经制作了一个返回对象的自定义钩子,我可以这样调用它:

const location = useGeoLocation(); 

我想将标记作为参数添加到 useGeoLocation 挂钩。只需在代码上调用函数并添加标记即可轻松实现。

目标

我的目标是在调用 useGeoLocation 之前确保标记包含一些值。现在,geoLocation hooks 参数返回 null 值,因为应用程序没有时间去 fetchMarkers 和更新状态。

我试过了

我的第一个想法是做这样的事情:

  if (markers) {
  const location = useGeoLocation(markers);
  }

当然,就像rules of hooks 中所说的那样,钩子不能有条件地使用。

2022 年 1 月 10 日更新 - useGeoLocation 挂钩

我在这里获取用户位置。成功后,我会将用户位置与一组标记进行比较,并找到最接近用户的位置。 如果出错,我将只返回一个预定义的位置。

这不起作用,因为 onSuccess 在标记(null)中有任何数据之前执行。我不确定如何在这里使用 if - else 语句,因为我也在使用 useEffect & useState。

有人可以帮忙吗?

const useGeoLocation = (markers) => {

const [location, setLocation] = useState({
loaded: false,
coordinates: { lat: "", lng: "" },
 });

const onSuccess = (location) => {
// User location succesfully fetched, converting data format.
const targetPoint = turf.point([
  location.coords.latitude,
  location.coords.longitude,
]);

// Fetching data from markers parameter and converting data format.
var arr = [];
markers.map((marker) => arr.push(turf.point(marker.location)));
var points2 = turf.featureCollection(arr);

// Calculating which marker is nearest to targetPoint.
var nearest = turf.nearestPoint(targetPoint, points2);

// Setting location of nearest marker to usestate.
setLocation({
  loaded: true,
  coordinates: {
    lat: nearest.geometry.coordinates[0],
    lng: nearest.geometry.coordinates[1],
  },
});
};

const onError = () => {
setLocation({
  loaded: true,
  coordinates: {
    lat: 65.024335,
    lng: 27.277089,
  },
  });
  };

useEffect(() => {
if (!("geolocation" in navigator)) {
  onError();
}

navigator.geolocation.getCurrentPosition(onSuccess, onError);
}, []);

return location;
};

【问题讨论】:

  • 钩子不能有条件地使用。只需执行useGeoLocation(markers),在自定义钩子中使用if...else 条件语句。例如。 if(!markers) return someFallback; // do something with makers
  • 可以分享geoLocation挂钩代码吗?
  • 我分享了 useGeoLocation 挂钩代码到我的问题,请看一下!

标签: javascript reactjs async-await react-hooks axios


【解决方案1】:

在useGeoLocation的useEffect hook的依赖数组中添加标记,如果标记可用则调用navigator.geolocation.getCurrentPosition(onSuccess, onError),在else部分可以调用setLocation()。

const useGeoLocation = (markers) => {
  const [location, setLocation] = useState({
    loaded: false,
    coordinates: { lat: "", lng: "" },
  });

  
  useEffect(() => {
      if (markers) {
          if (!("geolocation" in navigator)) {
            onError();
          }
      
          navigator.geolocation.getCurrentPosition(onSuccess, onError);
      } else {
        setLocation();
      }
  }, [markers]);

  return location;
};

【讨论】:

    猜你喜欢
    • 2021-11-05
    • 2020-12-30
    • 2020-12-25
    • 1970-01-01
    • 2019-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-10
    相关资源
    最近更新 更多