React.js中的getCurentPosition()不更新状态

时间:2020-06-16 11:50:03

标签: javascript reactjs async-await geolocation

我正在尝试获取用户在我应用中的当前位置,但是即使我在console.log上看到它时,它也无法正常工作。 我正在使用异步函数来检索它,但是我必须做错了什么,而且我无法弄清楚问题出在哪里。

ContextState

import React, { useReducer } from "react";
import RestContext from "./restContext";
import RestReducer from "./restReducer";
import Yelp from "../../Util/Yelp";
import { getCurrentPosition } from "../../Util/GeoLocation";
import {
  GET_RESTAURANTS,
  GET_INFO_RESTAURANT,
  CLEAR_SEARCH,
  SET_LOADING,
  GET_LOCATION,
} from "../../types";

const RestState = (props) => {
  const initalState = {
    restaurants: [],
    restaurant: {},
    loading: false,
    location: {},
  };

  const [state, dispatch] = useReducer(RestReducer, initalState);

  // Get Restaurants
  const getRestaurants = async (text) => {
    setLoading();

    let restaurants = await Yelp.searchRestaurants(text);

    if (restaurants) {
      dispatch({ type: GET_RESTAURANTS, payload: restaurants });
    } else {
      dispatch({ type: GET_RESTAURANTS, payload: [] });
    }
  };

  // Get info Restaurants

  const getRestaurantInfo = async (id) => {
    setLoading();
    let restaurant = await Yelp.searchRestaurantsInfo(id);

    if (restaurant) {
      dispatch({ type: GET_INFO_RESTAURANT, payload: restaurant });
    } else {
      dispatch({ type: GET_INFO_RESTAURANT, payload: {} });
    }
  };

  // Clear search

  const clearSearch = () => dispatch({ type: CLEAR_SEARCH });

  // Set loading

  const setLoading = () => dispatch({ type: SET_LOADING });

  // Get location

  const fetchCoordinates = async () => {
    try {
      const coords = await getCurrentPosition();
      dispatch({ type: GET_LOCATION, payload: coords });
    } catch (error) {
      // Handle error
      console.error(error);
    }
  }

  return (
    <RestContext.Provider
      value={{
        restaurants: state.restaurants,
        restaurant: state.restaurant,
        loading: state.loading,
        getRestaurants,
        clearSearch,
        getRestaurantInfo,
        fetchCoordinates,
      }}
    >
      {props.children}
    </RestContext.Provider>
  );
};

export default RestState;

是减速器

import {
  GET_RESTAURANTS,
  GET_INFO_RESTAURANT,
  CLEAR_SEARCH,
  SET_LOADING,
  GET_LOCATION,
} from "../../types";

export default (state, action) => {
  switch (action.type) {
    case GET_RESTAURANTS:
      return { ...state, restaurants: action.payload, loading: false };
    case GET_INFO_RESTAURANT:
      return { ...state, restaurant: action.payload, loading: false };
    case CLEAR_SEARCH:
      return { ...state, restaurants: [], loading: false };
    case SET_LOADING:
      return {
        ...state,
        loading: true,
      };
    case GET_LOCATION:
      return { ...state, location: action.payload };
    default:
      return state;
  }
};

还有应该使用的主页

import React, { Fragment, useEffect, useContext } from "react";
import Search from "../../Components/restaurants/Search";
import Alert from "../../Components/layout/Alert";
import Navbar from "../../Components/layout/Navbar";
import DisplayRestaurants from "../../Components/layout/DisplayRestaurants";
import Footer from "../../Components/layout/Footer";
import { Waypoint } from "react-waypoint";
import RestContext from "../context/restaurant/restContext";

const Home = () => {
  const restContext = useContext(RestContext);

  useEffect(() => {
    restContext.fetchCoordinates();
    // eslint-disable-next-line
  }, []);

  const handleWaypointEnter = () => {
    document.querySelector("nav").classList.remove("fixed");
  };
  const handleWaypointLeave = () => {
    document.querySelector("nav").classList.add("fixed");
  };

  return (
    <section className="main-home">
      <Fragment>
        <Navbar />
        <Search />
        <Alert />
        <Waypoint onEnter={handleWaypointEnter} onLeave={handleWaypointLeave} />
        <DisplayRestaurants />
        <Footer />
      </Fragment>
    </section>
  );
};

export default Home;

getCurrentPosition

export function getCurrentPosition(options = {}) {
  return new Promise((resolve, reject) => {
    navigator.geolocation.getCurrentPosition(resolve, reject, options);
  });
}

coord obj

GeolocationCoordinates {latitude: 52.3555177, longitude: -1.1743196999999999, altitude: null, accuracy: 372529, altitudeAccuracy: null, …}
accuracy: 372529
altitude: null
altitudeAccuracy: null
heading: null
latitude: 52.3555177
longitude: -1.1743196999999999
speed: null
__proto__: GeolocationCoordinates

感谢您的帮助

1 个答案:

答案 0 :(得分:1)

您可以试试吗?

它返回一个承诺,因此理论上应该能够使用.then


    getCurrentPosition().then((res) => {
      console.log(res) // check what `res` is
      dispatch({ type: GET_LOCATION, payload: res.cords });
    })