【问题标题】:How to chain 2 API calls with redux thunk?如何使用 redux thunk 链接 2 个 API 调用?
【发布时间】:2017-04-27 11:06:19
【问题描述】:

我正在制作一个天气应用程序,它通过对 freegeoip.com 进行 API 调用来检测您当前位置的坐标,然后将这些坐标用于对 openweathermap.org 进行 API 调用以获取您当前位置的天气。

我将如何使用 redux thunk 做到这一点?

这是我当前的动作创建者代码:

import axios from 'axios';

export const FETCH_CURRENT_CITY = 'FETCH_CURRENT_CITY';

const API_KEY = '95108d63b7f0cf597d80c6d17c8010e0';
const ROOT_URL = `http://api.openweathermap.org/data/2.5/weather?appid=${API_KEY}`;

export function fetchCurrentCityCoords() {
  const request = axios.get('http://freegeoip.net/json/');

  console.log('Request coords:', request);

  return (dispatch) => {
    request.then(({response}) => {
      dispatch(fetchCurrentCityWeather(response));
    });
  };
}

export function fetchCurrentCityWeather(coords) {
  const lat = coords.data.latitude;
  const lon = coords.data.longitude;

  const url = `${ROOT_URL}&lat=${lat}&lon=${lon}`;
  const request = axios.get(url);

  console.log('Request weather:', request);

  return (dispatch) => {
    request.then(({response}) => {
      dispatch({
        type: FETCH_CURRENT_CITY,
        payload: response
      })
    });
  };
}

控制台日志:

Request coords: Promise {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined}

Uncaught (in promise) TypeError: Cannot read property 'latitude' of undefined
    at fetchCurrentCityWeather (bundle.js:26131)
    at bundle.js:26125

【问题讨论】:

    标签: reactjs redux redux-thunk


    【解决方案1】:

    您确定 API response 拥有 data 属性吗?
    尝试调试fetchCurrentCityWeather 函数的第一行并检查coords 的内容,或者尝试console.log(coords); 来查看它的对象结构。

    也许是这样的:

     const lat = coords.data.latitude;
     const lon = coords.data.longitude;
    

    应该是这样的:

     const lat = coords.latitude;
     const lon = coords.longitude;
    

    编辑
    关注您的评论,
    出于调试目的,尝试将您的 fetchCurrentCityWeather 函数编辑为此代码并查看打印到控制台的内容:

    export function fetchCurrentCityWeather(coords) {
        console.log(coords);
    
      //const lat = coords.data.latitude;
      //const lon = coords.data.longitude;
    
      //const url = `${ROOT_URL}&lat=${lat}&lon=${lon}`;
      //const request = axios.get(url);
    
      //console.log('Request weather:', request);
    
      //return (dispatch) => {
        //request.then(({response}) => {
         // dispatch({
            //type: FETCH_CURRENT_CITY,
           // payload: response
          //})
        //});
     // };
    }  
    

    编辑 #2
    根据您的评论,您将获得undefined,因此您不能在其上使用.map。这是您对错误的回答。
    至于你为什么得到undefined,我想是因为这段代码:

     return (dispatch) => {
        request.then(({response}) => {
          dispatch(fetchCurrentCityWeather(response));
        });
      }; 
    

    您正在使用此 {response}response 参数进行“解构”。
    试试这个:

     return (dispatch) => {
        request.then((response) => {
          dispatch(fetchCurrentCityWeather(response));
        });
      }; 
    

    【讨论】:

    • 我也有同样的怀疑,不幸的是它仍然不起作用。这是我得到的控制台日志消息:Uncaught (in promise) TypeError: Cannot read property 'latitude' of undefined at fetchCurrentCityWeather (bundle.js:26132) at bundle.js:26126
    • 按照您的建议注释掉,这就是控制台显示的内容:Uncaught (in promise) Error: Actions must be plain objects. Use custom middleware for async actions. at dispatch (bundle.js:20476) at bundle.js:26418 at dispatch (bundle.js:21229) at bundle.js:26126
    • 是的,这是意料之中的,因为您没有返回有效的Action 对象,但是console.log(coords); 行呢,它没有打印coords 的值?
    • 返回未定义
    • @JosephLiu 我再次编辑了我的答案。尝试通过 response 而不对其进行解构。
    【解决方案2】:

    未捕获(承诺中)类型错误:无法读取未定义的属性“纬度” 在 fetchCurrentCityWeather (bundle.js:26131) 在 bundle.js:26125

    问题似乎是您的const lat = coords.data.latitude 它未定义。

    所以你必须检查是否

    return (dispatch) => {
    request.then(({response}) => {
      dispatch(fetchCurrentCityWeather(response));
    });
    

    CallsfetchCurrentCityWeather 使用正确的 response 对象,您希望具有属性 data.latitudedata.longitude 您似乎错误地引用了。

    建议。

    console.log(coords);fetchCurrentCityWeather 函数中查看它是否具有这些属性。

    【讨论】:

    • 这是它显示的内容:Uncaught (in promise) Error: Actions must be plain objects. Use custom middleware for async actions. at dispatch (bundle.js:20476) at bundle.js:26418 at dispatch (bundle.js:21229) at bundle.js:26126
    • 好的,上一层怎么样?在发送fetchCurrentCityWeather 之前,将整行注释掉。尝试在那里console.log(response)。是你需要的对象吗? @JosephLiu
    • 返回未定义return (dispatch) => { request.then(({response}) => { console.log('response:',response); // dispatch(fetchCurrentCityWeather(response)); }); };
    • @JosephLiu 考虑上面 Sag1v 的更新答案。传递响应而不破坏它。
    猜你喜欢
    • 2019-04-06
    • 2018-12-19
    • 2018-01-31
    • 2017-02-04
    • 2017-05-11
    • 2019-01-24
    • 2020-07-21
    • 2018-10-16
    • 2017-08-28
    相关资源
    最近更新 更多