我在使用redux過程中遇到Actions must be plain objects. Use custom middleware for async actions.異常的分析

原因一:使用異步actions時(shí),沒有配置redux-thunk這個(gè)中間件

中間件就是一個(gè)函數(shù),對store.dispatch方法進(jìn)行了改造,在發(fā)出 Action 和執(zhí)行 Reducer 這兩步之間,添加了其他功能。

import { applyMiddleware, createStore } from 'redux';
import createLogger from 'redux-logger';
const logger = createLogger();

const store = createStore(
  reducer,
  applyMiddleware(logger)
);

上面代碼中,redux-logger提供一個(gè)生成器createLogger,可以生成日志中間件logger。然后,將它放在applyMiddleware方法之中,傳入createStore方法,就完成了store.dispatch()的功能增強(qiáng)。

const store = createStore(
  reducer,
  applyMiddleware(thunk, promise, logger)
);

applyMiddleware 是Redux 的原生方法,作用是將所有中間件組成一個(gè)數(shù)組,依次執(zhí)行。

原因二:調(diào)用action方法時(shí),方法體內(nèi)部并沒有調(diào)用dispatch。

/**
 * 加載路由或iframe
 *
 * @param menu      需要加載的菜單
 */
export function onLoadMain(menu) {
    let routeUrl = menu.routeurl;
    let url = menu.url;
    console.log("routeUrl : ",routeUrl);
    if (routeUrl) {
        weaHistory.push({pathname: routeUrl});

        document.getElementById('e9frameMain').style.visibility = 'hidden';
        document.getElementById('e9routeMain').style.display = 'block';
        // let mainframe = document.getElementById('mainFrame');
        // mainframe.src = 'about:blank';
        document.getElementById('mainFrame').src = 'about:blank';
    } else if (url && url != 'javascript:void(0);') {
        let target = menu.target || 'mainFrame';
        if ('mainFrame' != target) {
            window.open(url, target);
        } else {
            // let mainframe = document.getElementById('mainFrame');
            // mainframe.src = url;
            document.getElementById('mainFrame').src = url;
            document.getElementById('e9frameMain').style.visibility = 'visible';
            document.getElementById('e9routeMain').style.display = 'none';
        }
    }
}

以上是一個(gè)普通的function,放在action的js文件中,如果你使用了如下方式去調(diào)用這個(gè)方法,雖然能成功調(diào)用,但在配置了redux-thunk這個(gè)中間件的情況下,你發(fā)起的任何action方法,都會走thunk這個(gè)中間件,一旦方法體內(nèi)沒有dispatch這個(gè)方法,則會報(bào)Actions must be plain objects. Use custom middleware for async actions這個(gè)異常。

import * as themeActions from '../../../actions/theme';

handleClick(e) {

        const {actions}=this.props;
        let urlParams= {
            iframeUrl: e.key,
            routeUrl:e.item.props.routeurl
        }

        actions.updateMenusUrl(urlParams);*/
        let menuInfo={
            routeurl:e.item.props.routeurl,
            url: e.key,
            target:'mainFrame'
        }
        //通過派生action的形式來調(diào)用這個(gè)方法
        actions. onLoadMain(menuInfo);

function mapStateToProps(state) {
    const {middleTheme} = state;

    return {
        backEndMenuUrl: middleTheme.get('backEndMenuUrl'),
        columnMenuInfo:middleTheme.get('columnMenuInfo')
    }
}

function mapDispatchToProps(dispatch) {
    return {
        actions: bindActionCreators(themeActions, dispatch)
    };
}

module.exports = connect(mapStateToProps, mapDispatchToProps)(E9LeftMenusTree);

所以常規(guī)function最好通過import導(dǎo)入的形式去調(diào)用就OK了,如下:

import {onLoadMain} from '../../../actions/theme';

handleClick(e) {

        const {actions}=this.props;
        let urlParams= {
            iframeUrl: e.key,
            routeUrl:e.item.props.routeurl
        }

        actions.updateMenusUrl(urlParams);*/
        let menuInfo={
            routeurl:e.item.props.routeurl,
            url: e.key,
            target:'mainFrame'
        }
        //常規(guī)import組件形式調(diào)用function
        onLoadMain(menuInfo);
    }

最后分享下我在解決這個(gè)問題中參考的阮大大的關(guān)于redux中間件的介紹Redux中間件和異步操作

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容