如何在Redux中通过API获取数据?

30

我是一个reactjs/redux的初学者,找不到一个简单易用的示例来在redux应用程序中使用API调用检索数据。我猜可以使用jquery ajax调用,但可能还有更好的选择?


https://github.com/argelius/react-onsenui-redux-weather/tree/master/api - J Santosh
可能是如何在react-redux中进行HTTP请求?的重复问题。 - Harkirat Saluja
2个回答

53

JSfiddle; http://jsfiddle.net/cdagli/b2uq8704/6/

它使用了redux、redux-thunk和fetch。

Fetch方法;

function fetchPostsWithRedux() {
    return (dispatch) => {
    dispatch(fetchPostsRequest());
    return fetchPosts().then(([response, json]) =>{
        if(response.status === 200){
        dispatch(fetchPostsSuccess(json))
      }
      else{
        dispatch(fetchPostsError())
      }
    })
  }
}

function fetchPosts() {
  const URL = "https://jsonplaceholder.typicode.com/posts";
  return fetch(URL, { method: 'GET'})
     .then( response => Promise.all([response, response.json()]));
}

上述使用的操作:

(注意:您可以定义许多操作,例如fetchPostRequest可用于显示加载指示器。或者您可以在不同的HTTP状态代码情况下分派不同的操作。)

function fetchPostsRequest(){
  return {
    type: "FETCH_REQUEST"
  }
}

function fetchPostsSuccess(payload) {
  return {
    type: "FETCH_SUCCESS",
    payload
  }
}

function fetchPostsError() {
  return {
    type: "FETCH_ERROR"
  }
}

在你的reducer中,你可以将帖子加载到状态中;

const reducer = (state = {}, action) => {
  switch (action.type) {
    case "FETCH_REQUEST":
      return state;
    case "FETCH_SUCCESS": 
      return {...state, posts: action.payload};
    default:
      return state;
  }
} 

将组件连接后,您可以访问其状态和操作。

connect(mapStateToProps, {fetchPostsWithRedux})(App);

奇怪的是,使用这段代码时我得到了 Uncaught (in promise) Error: Reducers may not dispatch actions. 的错误提示。 - csilk
返回 Promise.all([response, response.json()]) 有什么作用?为什么不返回 response.json() - tim-phillips

11

创建一个操作,其中执行对您的API的请求。您可以使用像axios或fetch这样返回promise的库。

actions/index.js:

import axios from 'axios';

export const FETCH_SOMETHING= 'FETCH_SOMETHING;
const ROOT_URL = 'http://api.youapi.com';

export function fetchWeather(city) {

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

    return {
        type: FETCH_SOMETHING,
        payload: request
    };
}

然后在一个reducer中,一旦promise被解决,按以下方式消耗promise的结果:

reducers/reducer_something.js:

import { FETCH_SOMETHING} from '../actions/index';

export default function(state = [], action) {
    switch (action.type) {
        case FETCH_SOMETHING:
        return [ action.payload.data, ...state ];
    }

    return state;
}

这段代码是从Stephen Grider那里借来的。这是他的存储库:https://github.com/StephenGrider/ReduxCasts/tree/master/weather/src


你有Plunker或者其他什么吗? - bier hier
不可以,但是你可以克隆我编辑过并测试通过的myresponse示例。 - Franco
为什么在reducer中不需要使用.then()来确保Promise已经被执行并且data不是undefined - jhuang
2
@jhuang 很好的问题。当我说“一旦解决,按如下方式使用承诺结果”时,我忘了提到一个例子,由Stephen Grided提供,使用了一个名为redux-promise的库,必须在入口点中应用如下:applyMiddleware(ReduxPromise)(createStore)。该库处理承诺,使您的代码更加清晰。https://www.npmjs.com/package/redux-promise - Franco

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接