反应太多重新渲染

时间:2021-01-06 15:54:26

标签: reactjs geolocation react-hooks

我知道有很多关于这个错误的问题,但我试图找到这个特定问题的解决方案。

在子组件中,我获取用户的地理位置并在数据到达时返回一个对象。

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

  const onSuccess = (location) => {
    setLocation({
      loaded: true,
      coordinates: {
        lat: location.coords.latitude,
        lng: location.coords.longitude,
      },
    });
  };

  const onError = (error) => {
    setLocation({
      loaded: true,
      error: {
        code: error.code,
        message: error.message,
      },
    });
  };

  useEffect(() => {
    if (!("geolocation" in navigator)) {
      onError({
        code: 0,
        message: "Geolocation not supported",
      });
    }

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

  return location;
};

在我的父组件中,我想使用 React 钩子更新我的状态

import { LocateUser } from "../components";

export default () => {
  const [userPos, setUserPos] = useState({ lat: "", lon: "" });
  const location = LocateUser();

  if (location.loaded) {
     console.log(location.coordinates.lat);
     setUserPos({ // this creates the error
       lat: location.coordinates.lat,
       lon: location.coordinates.lng,
     });
  }

  return (
    <React.Fragment>
        { location.loaded ? JSON.stringify(location) : 'No location found' }
    </React.Fragment>
  );
}

我已经尝试使用 useEffect 和其他变通方法,但没有找到使其工作的解决方案。 问题是第一次加载子组件时,地理位置响应为空,稍后它返回带有数据的对象。 从子组件获取响应并更新父组件状态的解决方案是什么? 提前致谢

1 个答案:

答案 0 :(得分:0)

再包装一个useEffect

useEffect(() => {
  if (location.loaded) {
     console.log(location.coordinates.lat);
     setUserPos({
       lat: location.coordinates.lat,
       lon: location.coordinates.lng,
     });
  }
}, [location]) // location inside dependency array of the side effect

这样 location 返回的 LocateUser() 的更新似乎是一个自定义钩子,被“监听”并调用副作用来更新父组件的状态。