【问题标题】:Use redux-thunk with redux-promise-middleware in the correct way以正确的方式将 redux-thunk 与 redux-promise-middleware 一起使用
【发布时间】:2017-07-29 17:23:23
【问题描述】:

我正在一个使用 react 和 redux 的项目中工作,我足够新,所以我试图更好地了解如何一起使用 redux-thunk 和 redux-promise。 您可以在下面看到我的文件,在我的操作中,我创建了一个获取通用函数 apiFetch() 以便在每次需要获取时使用。此函数返回一个承诺,我将在 loadBooks() 中解决,代码正在运行并且记录已上传,但是当我检查操作日志时,我发现第一个操作未定义,在 BOOKS_LOADING 之后, LOAD_BOOKS、BOOKS_LOADING 和 LOAD_BOOKS_SUCCESS。

我有两个问题:

1) 为什么第一个操作未定义,而我使用的是 LOAD_BOOKS 而不是 LOAD_BOOKS_START?

action @ 22:54:37.403 undefined
core.js:112  prev state Object {activeBook: null, booksListing: Object}
core.js:116  action function (dispatch) {
        var url = './src/data/payload.json';
        dispatch(booksIsLoading(true));
        return dispatch({
          type: 'LOAD_BOOKS',
          payload: new Promise(function (resolve) {
…
core.js:124  next state Object {activeBook: null, booksListing: Object}
action @ 22:54:37.404 BOOKS_LOADING
action @ 22:54:37.413 LOAD_BOOKS
action @ 22:54:39.420 BOOKS_LOADING
action @ 22:54:39.425 LOAD_BOOKS_SUCCESS

2) 例如,如果获取的 url 错误,我希望看到操作 LOAD_BOOKS_ERROR,而不是日志的结果:

action @ 23:06:06.837 undefined action @ 23:06:06.837 BOOKS_LOADING
action @ 23:06:06.846 LOAD_BOOKS GET
http://localhost:8000/src/data/payldoad.json 404 (Not Found) error
apiFetch Error: request failed at index.js:66 error 
TypeError: Cannot read property 'json' of undefined at index.js:90

如果我不使用 apiFetch(),而是使用正常的 fetch 函数,那么一切正常,这也是错误的一部分,但无论如何 LOAD_BOOKS 不是 LOAD_BOOKS_START。

提前感谢您的帮助!

configureStore.js

import { createStore, applyMiddleware, compose, preloadedState } from 'redux';
import reducers from './configureReducer';
import configureMiddleware from './configureMiddleware';

const middleware = configureMiddleware();
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ||   compose;
const store = createStore(reducers, preloadedState, composeEnhancers(applyMiddleware(...middleware)));
export default store;

actions/index.js

import fetch from 'isomorphic-fetch';

export const booksIsLoading = (bool) => {
  return {
    type: 'BOOKS_LOADING',
    booksLoading: bool,
  };
};

const delay = ms => new Promise(resolve => setTimeout(resolve, ms));

export const apiFetch = (url) => {
  const getPromise = () => (
    fetch(url, {
      method: 'GET',
    })
      .then((response) => {
        if (response.status !== 200) {
          throw Error('request failed');
        }
        return response;
      })
      .catch((err) => {
        console.log('error apiFetch', err);
        // dispatch(fetchBooksError(true));
      })
  );
  return getPromise();
};

export const loadBooks = () => (dispatch) => {
  const url = './src/data/payload.json';
  dispatch(booksIsLoading(true));
  return dispatch({
    type: 'LOAD_BOOKS',
    payload: new Promise((resolve) => {
      delay(2000).then(() => {
        apiFetch(`${url}`)
          // fetch(`${url}`, {
          //   method: 'GET',
          // })
          .then((response) => {
            resolve(response.json());
            dispatch(booksIsLoading(false));
          }).catch((err) => {
            console.log('error', err);
          });
      });
    }),
  });
};

constants/application.js

export const LOAD_BOOKS = 'LOAD_BOOKS';

reducers/reducer_book.js

import initialState from '../model.js';
import * as types from '../constants/application';

export default function (state = initialState, action) {
  switch (action.type) {
    case `${types.LOAD_BOOKS}_SUCCESS`: {
      console.log('reducer', action.payload);
      const data = action.payload.data.items;
      const items = Object.values(data);

      if (items.length > 0) {
        return {
          ...state,
          books: Object.values(data),
          booksFetched: true,
          booksError: false,
        };
      }

      return state;
    }

    case `${types.LOAD_BOOKS}_ERROR`: {
      return {
        ...state,
        booksError: true,
      };
    }

    case 'BOOKS_LOADING':
      return {
        ...state,
        booksLoading: action.booksLoading,
      };

    default:
      return state;
  }
}

【问题讨论】:

    标签: javascript reactjs redux redux-thunk redux-promise-middleware


    【解决方案1】:

    您是按什么顺序指定中间件的?

    以下用法会使操作变得未定义:

    'applyMiddleware(reduxPromiseMiddleware(), reduxThunk)'

    请将顺序更改为:(thunk first!)

    'applyMiddleware(reduxThunk, reduxPromiseMiddleware())'

    【讨论】:

      猜你喜欢
      • 2018-07-08
      • 1970-01-01
      • 2021-04-14
      • 2017-02-04
      • 2016-08-26
      • 2020-02-08
      • 2018-11-09
      • 2018-05-05
      相关资源
      最近更新 更多