任何人都可以解释中间件在此示例中的作用https://github.com/erikras/react-redux-universal-hot-example/ 它不支持真正的api请求吗?
export default function clientMiddleware(client) {
return ({dispatch, getState}) => {
return next => action => {
if (typeof action === 'function') {
return action(dispatch, getState);
}
const { promise, types, ...rest } = action;
if (!promise) {
return next(action);
}
const [REQUEST, SUCCESS, FAILURE] = types;
next({...rest, type: REQUEST});
const actionPromise = promise(client);
console.log('client ');
console.log(client);
actionPromise.then(
(result) => next({...rest, result, type: SUCCESS}),
(error) => next({...rest, error, type: FAILURE})
).catch((error)=> {
console.error('MIDDLEWARE ERROR:', error);
next({...rest, error, type: FAILURE});
});
return actionPromise;
};
};
}
答案 0 :(得分:0)
在了解clientMiddleware的功能之前,您需要了解以下文件的用途:
src/helpers/ApiClient.js
:一个带有一组辅助方法来执行API调用的类
src/redux/create.js
:
此方法接收ApiClient
实例作为参数client
这与clientMiddleware
得到的参数相同
现在是clietMiddleware
,工作在代码中被注释
// The clientMiddleware basically aims to intercept actions which performs API call
// and it controls the dispatch of SUCCESS/FAILURE actions based on response
export default function clientMiddleware(client) {
return ({dispatch, getState}) => {
return next => action => {
// action creator is expected to return an object but
// if we get a function instead, lets unwrap the top layer
// by invoking the method and see if the action creator is inside
if (typeof action === 'function') {
return action(dispatch, getState);
}
// destructure properties from action object
const { promise, types, ...rest } = action;
// the middleware can work only if the Object returned by
// the action creator has a key 'promise' which is assigned
// a function that returns promise (essentially your API call)
if (!promise) {
// no 'promise' key? that means this action is not an API call
// let's pass this action to next middleware
return next(action);
}
// destructures elements from types array
// REQUEST = types[0]
// SUCCESS = types[1]
// FAILURE = types[2]
const [REQUEST, SUCCESS, FAILURE] = types;
// Call next middleware with action.type = REQUEST
// this will eventually get dipatched and the REQUEST reducer will get executed
// Invokes a reducer just before the API call
// a chance to set flags like 'loading': { ...state, loading: true }
next({ ...rest, type: REQUEST });
// as I said before 'promise' is a function we got by destructuring 'actions'
// and that function receives instance of ApiClient as parameter
// thus in turn a promise is returned and we are storing that to a variable here
const actionPromise = promise(client);
// as the name says, 'actionPromise'' is a JavaScipt promise, a 'then'able one.
actionPromise.then(
// on succesfull completion of the API call dispatch the SUCCESS action with result
// from API response, any additional parameters required by the reducer goes in ...rest
(result) => next({ ...rest, result, type: SUCCESS }),
// similar to the success case, we dipatch the FAILURE action with error when API fails
(error) => next({ ...rest, error, type: FAILURE })
).catch((error)=> {
next({ ...rest, error, type: FAILURE });
});
return actionPromise;
};
};
}