【问题标题】:Dispatch event in middleware中间件中的调度事件
【发布时间】:2019-09-11 17:15:57
【问题描述】:

我的 react-redux 应用中有两个中间件。

  1. 首先是 API 中间层,它向服务器发送请求并从中解析答案。
  2. 第二个是Auth中间件,它将JWT存储在本地存储中并检查来自服务器的响应是否为401代码,我们必须刷新我们的JWT。

在第二个中间件中,我尝试调用store.dispatch。在 redux devToolsExtension 中,我可以看到新操作,但此操作不会转到第一个中间件..

代码。 第一个中间件:

const apiMiddleware = store => next => action => {

    const {api, type, ...rest} = action;
    if (!api) {
        return next(action);
    }

    next({
        type: type + START,
        ...rest
    });

    const { url } = api;
    let params = getParamsForApiCall(api);
    let statusCode;

    // TODO timeout from settings
    timeout(5000, fetch(url, params).then(response => {
        statusCode = processResponse(response);
        return response.text();
    //
    })).then(text => {
        let nextType = processAnwer(text, statusCode);
        let typeResult = type + nextType;
        console.log('Type result action: ', typeResult);

        return next({type: typeResult, statusCode, responce: text, ...rest})
    //
    }).catch(error => {
        processError(error)
    })
};

第二个:

import {SUCCESS, UNAUTH} from "../../Constants";
import {USER, LOGIN, CHECK_JWT, REFRESH_TOKEN, LOGOUT, userRefreshToken, userLogout } from "../AC/User"
import { HTTP_CODE_UNAUTH }  from "../../Constants/http"

import { saveJWTToStore, clearJWTFormStore } from '../../Utils/jwt'

const authMiddleware = ({ dispatch }) => next => action => {
    const { type, statusCode, responce, ...rest } = action;

    next(action);

    switch (type) {
    case USER + REFRESH_TOKEN + UNAUTH:
    case USER + CHECK_JWT + UNAUTH:
        console.log('UNAUTH have to logout');
        dispatch(userLogout());
        break;
    // ---------
    case USER + CHECK_JWT + SUCCESS:
    case USER + LOGIN + SUCCESS:
        let obj = JSON.parse(responce);
        let token = obj['token'];
        action = Object.assign(action, {token: token});
        saveJWTToStore(token);
        break;
    // ---------
    case USER + LOGOUT:
        console.log('Remove JWT from localStore');
        clearJWTFormStore();
        break;
    // ---------
    default:
      let errAuth = statusCode === HTTP_CODE_UNAUTH;
      if (errAuth) {
        console.log(`Need to refresh JWT`);

        // !!! this dispatch does not word as well
        dispatch(userRefreshToken());
      }

    }
};

export default authMiddleware;

【问题讨论】:

    标签: reactjs react-redux


    【解决方案1】:

    编写中间件的一个惯例是你应该总是返回next()的结果。这是为了确保中间件返回另一个版本的 store 并保持中间件链正常工作。
    回到上面的示例,在您的第二个中间件中,您不返回 next() 的值,因此其他中间件不会收到您更新的存储。修复它:

    let result = next(action);
    ...
    return result;
    

    或者简单地说:

    ...
    return next(action);
    

    【讨论】:

    • 谢谢。但我也尝试过这个解决方案,但它也不起作用)我找到了解决方案:stackoverflow.com/questions/42217369/…。也许它会对某人充满希望。
    • 你能在这里发布你改变了什么吗?对其他人有帮助
    • 我发布的链接中有答案。
    • 很酷,所以用中间件设置商店有问题吗?我认为还建议在中间件中返回 next() 。
    • Yes and yes) 推荐的返回 next() 方法不起作用。但是使用 applyMiddleware(...middlewares) 的解决方案效果很好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-08
    • 1970-01-01
    • 1970-01-01
    • 2011-10-13
    • 2010-10-06
    • 2011-01-07
    • 1970-01-01
    相关资源
    最近更新 更多