我正在使用react和redux的項目,我已經足夠新,所以我想更好地瞭解如何使用redux-thunk和redux一起贊成。 下面你可以看到我的文件,在我的動作中,我創建了一個獲取通用函數apiFetch(),以便每次需要獲取時使用。這個函數返回一個承諾,我要在loadBooks()中解析,代碼正在工作,記錄被上傳,但是當我檢查行爲日誌時,我發現第一個行爲是未定義的,在有BOOKS_LOADING之後, LOAD_BOOKS,BOOKS_LOADING和LOAD_BOOKS_SUCCESS。以正確的方式使用redux-promise-middleware的redux-thunk
我有關於2個問題:
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)舉例來說,如果爲獲取網址是錯誤的,我期望看到的動作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(),但是正常的讀取函數,所有工作都正常,也是錯誤的一部分,除了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;
動作/ 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);
});
});
}),
});
};
常數/的application.js
export const LOAD_BOOKS = 'LOAD_BOOKS';
減速器/ 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;
}
}