ReactJS中的异步函数

人气:501 发布:2022-10-16 标签: asynchronous async-await components reactjs react-hooks

问题描述

我有一个父组件和子组件,我想知道如何使用子组件中的异步函数。我目前也在使用Reaction挂钩。

代码

import React, { useEffect, useState, useRef } from "react";

// reactstrap components
import { Card, Container, Row } from "reactstrap";

// core components
import Header from "components/Headers/Header.js";
import LocationSearchInput from "../../components/Places";
import { useAuthenticator } from "@aws-amplify/ui-react";
import * as queries from "../../graphql/queries";
import { API, graphqlOperation } from "aws-amplify";
import { geocodeByAddress, getLatLng } from "react-places-autocomplete";
import * as _ from "lodash";
import mapStyles from "./mapStyles";

const MapWrapper = ({data, loc}) => {
  const mapRef = useRef(null);
  // const [location, setLocation] = useState();
  console.log("child props", data, loc);

  console.log("foo child", loc);
  let location = null;
  if(loc.length >0){

  }



const latLongAddress = async () => {
  try {
    geocodeByAddress(loc[0].HomeLocation)
    .then(results => getLatLng(results[0]))
    .then(latLng => {console.log('Success', latLng); location=latLng})
    .catch(error => console.error('Error', error))
 } catch (err) {
     console.log('error facing location:', err)
 }
}
  useEffect(() => {

    console.log("child mount");
    if(loc.length > 0){
        var x = latLongAddress();
        console.log("value of x", x);
    }

    let google = window.google;
    let map = mapRef.current;
    if(location)
    {
      console.log("latLong", location);
    }
    let lat = "40.748817";
    let lng = "-73.985428";
    const myLatlng = new google.maps.LatLng(lat, lng);
    const mapOptions = {
      zoom: 12,
      center: myLatlng,
      scrollwheel: false,
      zoomControl: true,
      styles: mapStyles,
    };

    map = new google.maps.Map(map, mapOptions);

    const marker = new google.maps.Marker({
      position: myLatlng,
      map: map,
      animation: google.maps.Animation.DROP,
      title: "Light Bootstrap Dashboard PRO React!",
    });

    const contentString =
      '<div class="info-window-content"><h2>Light Bootstrap Dashboard PRO React</h2>' +
      "<p>A premium Admin for React-Bootstrap, Bootstrap, React, and React Hooks.</p></div>";

    const infowindow = new google.maps.InfoWindow({
      content: contentString,
    });

    google.maps.event.addListener(marker, "click", function () {
      infowindow.open(map, marker);
    });
  }, []);

  console.log("child render");
  return (
    <>
      <div
        style={{ height: `600px` }}
        className="map-canvas"
        id="map-canvas"
        ref={mapRef}
      ></div>
    </>
  );
};

const Maps = () => {
  const [foo, setFoo] = useState([]);

  const { user, signOut } = useAuthenticator((context) => [context.user]);

  const [pin, setPin] = useState([]);

  const fetchFoo = async () => {
    console.log(user.attributes.email);
    try {
      const todoData = API.graphql(
        graphqlOperation(queries.listEmployees, {
          filter: {
            Email: {
              eq: user.attributes.email,
            },
          },
        })
      ).then((response) => {
          console.log("fetch resp", response);
          setFoo(response.data.listEmployees.items);
        })
        .catch((err) => {
          console.log(err);
        });

    } catch (err) {
      console.log("error facing Todos:", err);
    }
  };
  console.log("parent render");

  useEffect(() => {
    console.log("parent mount")
    fetchFoo();
  }, []);

  var json = [{a: "a", b:"b"}]

  return (
    <>
      <Header />
      {/* Page content */}
      {/* {foo} */}
      <Container className="mt--7" fluid>
        <Row>
          <div className="col">
            {/* <LocationSearchInput /> */}
          </div>
        </Row>
        <Row>
          <div className="col">
            <Card className="shadow border-0">
              {/* <> */}
              <MapWrapper data={json} loc={foo}/>
              {/* </> */}
            </Card>
          </div>
        </Row>
      </Container>
    </>
  );
};

export default Maps;

推荐答案

如果要将代码执行阻止到带有AWait关键字的下一行,则只需要具有Async关键字的函数。

您的函数应该是这样的..

    const latLongAddress = async () => {
      try { let response = await geocodeByAddress(loc[0].HomeLocation);
setLocation(response.location)
     } catch (err) {
console.log(err)
setLocation(null)
     }
    }

现在要使用它,您首先需要提取lcoation,然后需要为此调用Google map API,您需要2个useEffect。 第一个:

在组件负载下运行。 UseEffect(()=>;{lanLongAdress()},[])

在LatLong地址中设置状态后,您需要其他Use Effect才能根据位置继续进行Google呼叫。

useEffect(() => {
if(location) {


   console.log("child mount");
    if(loc.length > 0){
        var x = latLongAddress();
        console.log("value of x", x);
    }

    let google = window.google;
    let map = mapRef.current;
    if(location)
    {
      console.log("latLong", location);
    }
    let lat = "40.748817";
    let lng = "-73.985428";
    const myLatlng = new google.maps.LatLng(lat, lng);
    const mapOptions = {
      zoom: 12,
      center: myLatlng,
      scrollwheel: false,
      zoomControl: true,
      styles: mapStyles,
    };

    map = new google.maps.Map(map, mapOptions);

}
 
),[location]}

538