【问题标题】:How can I use response data from an API to call another different API request in React UseEffect?如何使用来自 API 的响应数据在 React UseEffect 中调用另一个不同的 API 请求?
【发布时间】:2021-09-23 22:43:21
【问题描述】:

我想知道如何调用需要来自其他 API 的数据的 API。就我而言,我想获取坐标;纬度和经度,并使用这些进行另一个 API 调用以检索我需要的信息。

这里是 App.js 文件

import React from 'react';
import './App.css';
import CityInput from "./components/CityInput";
import {Container} from 'react-bootstrap';
import UseFetch from "./hooks/useFetch";
import {API_BASE_URL, API_KEY} from "./apis/config";
import WeatherList from "./components/WeatherList";

const App = () => {
    const {data, error, isLoading, setUrl} = UseFetch();

    const getContent = () => {
        if(error) return <h2>Error when fetching: {error}</h2>
        if(!data && isLoading) return <h2>LOADING...</h2>
        if(!data) return null;
        return <WeatherList weathers={data.list}/>
    };

    return (
      <Container className="App">
          {/* user types a city and clicks search*/}
          <CityInput onSearch={(city) => setUrl(`${API_BASE_URL}/data/2.5/forecast?q=${city}&appid=${API_KEY}&units=metric`)} />

          {getContent()}

      </Container>
    );
}

export default App;

这是我的 UseFetch.js 文件

import {useState, useEffect} from 'react';
import {API_BASE_URL, API_KEY} from "../apis/config";

const UseFetch = (initialUrl) => {
    const [data, setData] = useState(null);
    const [error, setError] = useState(null);
    const [isLoading, setIsLoading] = useState(null);
    const [url, setUrl] = useState(initialUrl);

    useEffect(() => {
        if(!url) return;
        setIsLoading(true);
        setData(null);
        setError(null);

        fetch(url)
            .then((response) => response.json())
            .then((data) => {
                setIsLoading(false);
                if(data.cod >= 400) {
                    setError(data.message);
                    return;
                }
                setData(data);
                console.log(data);

                console.log(data.city.coord.lat);
                console.log(data.city.coord.lon);


            })
            .catch((error) => {
                setIsLoading(false);
                setError(error);
            });
        //
        // console.log('HIIIIII'+ data);
        // fetch(`${API_BASE_URL}/data/2.5/onecall?lat=${data.city.coord.lat}&lon=${data.city.coord.lon}&exclude=minutely&appid=${API_KEY}`)
        //     .then((response) => response.json())
        //     .then((data2) =>  {
        //         setIsLoading2(false);
        //         setData2(data2);
        //         console.log(data2);
        //     })
        //     .catch((error2) => {
        //         setIsLoading2(false);
        //         setError2(error);
        //     });
    }, [url]);
    return { data, error, isLoading, setUrl};


};

export default UseFetch;

我想检索经度和经度,以便我可以进行另一个获取

fetch(`${API_BASE_URL}/data/2.5/onecall?lat=${data.city.coord.lat}&lon=${data.city.coord.lon}&exclude=minutely&appid=${API_KEY}`)

但这似乎不起作用。 我正在使用这些 API 作为参考:

https://openweathermap.org/forecast5

https://openweathermap.org/api/one-call-api

【问题讨论】:

    标签: reactjs api use-effect


    【解决方案1】:

    Initial Api 发回响应后立即调用它,例如:

    fetch(APIURL)
    .then(response => {
    /** do any operations using received response data **/
    
    /** Calling second api **/
    fetch(API_URL_ + response.data.url)
    .then(data => {
    setData(data)
    })
    .catch(error)
    }).catch(error)
    

    UseFetch.js

    import {useState, useEffect} from 'react';
    import {API_BASE_URL, API_KEY} from "../apis/config";
    
    const UseFetch = (initialUrl) => {
        const [data, setData] = useState(null);
        const [error, setError] = useState(null);
        const [isLoading, setIsLoading] = useState(null);
        const [url, setUrl] = useState(initialUrl);
    
        useEffect(() => {
            if(!url) return;
            setIsLoading(true);
            setData(null);
            setError(null);
    
            fetch(url)
                .then((response) => response.json())
                .then((data) => {
                    setIsLoading(false);
                    if(data.cod >= 400) {
                        setError(data.message);
                        return;
                    }
                    setData(data);
                    console.log(data);
    
                    console.log(data.city.coord.lat);
                    console.log(data.city.coord.lon);
    
      console.log('HIIIIII'+ data);
    fetch(`${API_BASE_URL}/data/2.5/onecall?lat=${data.city.coord.lat}&lon=${data.city.coord.lon}&exclude=minutely&appid=${API_KEY}`)
                 .then((response) => response.json())
                 .then((data2) =>  {
                     setIsLoading2(false);
                     setData2(data2);
                     console.log(data2);
                 })
                 .catch((error2) => {
                     setIsLoading2(false);
                     setError2(error);
                });
    
                })
                .catch((error) => {
                    setIsLoading(false);
                    setError(error);
                });
            
        }, [url]);
        return { data, error, isLoading, setUrl};
    
    
    };
    
    export default UseFetch;
    

    【讨论】:

      【解决方案2】:

      在将第一个响应保存在变量中后,您可以尝试链接另一个.then()??类似于:

      let anyVariable;
              
             fetch(url)
              .then((response) => response.json())
              .then((data) => {
                  setIsLoading(false);
                  if(data.cod >= 400) {
                      setError(data.message);
                      return;
                  }
                  anyVariable = data.city.coord
              })
              .then(() => {
                  fetch(`${API_BASE_URL}/data/2.5/onecall?lat=${anyVariable.lat}&lon=${anyVariable.lon}&exclude=minutely&appid=${API_KEY}`)
               .then((response) => response.json())
               .then((data2) =>  {
                   setIsLoading2(false);
                   setData2(data2);
                   console.log(data2);
               })
      
              })
      

      我认为使用 axios 和 async await 会更干净,性能更好。另请注意,useState 是异步的。

      【讨论】:

        猜你喜欢
        • 2022-01-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-14
        • 1970-01-01
        • 2018-07-22
        • 2021-06-06
        • 2021-06-19
        相关资源
        最近更新 更多