即使获取失败,React Redux ActionCreator的获取API也会始终成功

时间:2018-07-12 12:10:28

标签: javascript reactjs redux fetch

我正在构建一个使用自己的API的应用程序。 (正在为其运行nodejs服务器),无论如何,动作创建者都会将成功的actionCreator传递给reducer。

这是我的提取操作创建者:

export function fetchData() {
  return dispatch => {
    dispatch(fetchBegin());
    return fetch('/api/selectAll')
      .then(handleErrors)
      .then(res => res.json())
      .then(json => {
        dispatch(fetchSuccess(json));
        return json;
      })
      .catch(error => dispatch(fetchFailure(error)));
  };
}

这是“ index.js”操作中的其他功能

// Handle HTTP errors since fetch won't.
function handleErrors(response) {
  if (!response.ok) {
    throw Error(response.statusText);
  }
  return response;
}

export const fetchBegin = () => ({
  type: FETCH_DATA_BEGIN
});

export const fetchSuccess = data => ({
  type: FETCH_DATA_SUCCESS,
  payload: data
});

export const fetchFailure = error => ({
  type: FETCH_DATA_FAILURE,
  payload: error
});

这是我的travelReducer,我已经在文件顶部导入了操作类型

const initialState = {
  items: [],
  loading: false,
  error: null
};

export default function travelReducer(state = initialState, action) {
  console.log('action :', action.type);
  switch (action.type) {
    case FETCH_DATA_BEGIN:
      // Mark the state as "loading" so we can show a spinner or something
      // Also, reset any errors. We're starting fresh.
      return {
        ...state,
        loading: true,
        error: null
      };

    case FETCH_DATA_SUCCESS:
      // All done: set loading "false".
      // Also, replace the items with the ones from the server
      return {
        ...state,
        loading: false,
        items: action.payload
      };

    case FETCH_DATA_FAILURE:
      console.log('failure should be hit');
      // The request failed, but it did stop, so set loading to "false".
      // Save the error, and we can display it somewhere
      // Since it failed, we don't have items to display anymore, so set it empty.
      return {
        ...state,
        loading: false,
        error: action.payload,
        items: []
      };

    default:
      // ALWAYS have a default case in a reducer
      return state;
  }
}

然后我在travelList容器中使用它。我还导入了fetchTravel()函数,并在componentDidMount()上调用this.props.fetchTravel()

const mapStateToProps = state => ({
  data: state.travel.items,
  loading: state.travel.loading,
  error: state.travel.error
});

// // anything returned from this func will end up as props
// // on this container (this.props.fetchTravelData)
function mapDispatchToProps(dispatch) {
  // whenever fetchTravelData is called, the result should be passed to
  // ALL reducers
  return bindActionCreators({ fetchData: fetchData }, dispatch);
}

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(TravelList);

我的主要问题问题不是让它按预期进行获取,而是这样做了,但是从来没有调用错误actionCreator,即使我可以在.catch()中console.log“捕获错误”( ),它将记录。但是在reducer中没有更新。

要对此进行检查,我将console.log记录action.type,无论如何,即使记录了“错误捕获”日志,其动作类型也将是FETCH_DATA_SUCCESS。

拔出头发,所以任何建议都很好。

谢谢。

3 个答案:

答案 0 :(得分:0)

我认为您提供的代码中没有您的错误。如果您成功登录了调度fetchFailure的catch中的控制台,则说明您的提取逻辑正在工作。下一步的调试步骤可能是console.log(error)以确保您收到了您认为已收到的内容,以及console.log(fetchFailure(error))以确保您正在分派的操作是您认为正在分派的内容。

如果fetchFailure(error)返回错误操作,则减速器没有理由收到成功操作:至少在您提供的代码中没有。

答案 1 :(得分:0)

好吧,我是一个傻瓜:)我刚刚检查了我拥有的actionTypes,我意识到我已经两次成功提取数据成功了,无论失败还是成功。感谢您抽出宝贵时间提出建议。标记为已回答

答案 2 :(得分:-1)

由于引发错误,因此需要在化简器中引用error message,而不是错误对象(当前传递给catch处理程序的错误对象)。

case FETCH_DATA_FAILURE:
  console.log('failure should be hit');
  // The request failed, but it did stop, so set loading to "false".
  // Save the error, and we can display it somewhere
  // Since it failed, we don't have items to display anymore, so set it empty.
  return {
    ...state,
    loading: false,
    error: action.payload.message,
    items: []