任何人都可以解释中间件在这个例子中做了什么https://github.com/erikras/react-redux-universal-hot-example

时间:2016-11-30 13:34:15

标签: reactjs express redux middleware

任何人都可以解释中间件在此示例中的作用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;
};
};
}

1 个答案:

答案 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;
        };
    };
}