Reducer 返回未定义(Redux-Thunk 和 Promise)

Posted

技术标签:

【中文标题】Reducer 返回未定义(Redux-Thunk 和 Promise)【英文标题】:Reducer returned undefined (Redux-Thunk and Promise) 【发布时间】:2018-05-27 13:59:42 【问题描述】:

我已经在网上搜索了几个小时来寻找解决这个问题的方法。我找到了一些相关问题的提示和解决方案,但不是这个问题。也许我的商店配置错误,或者我定义了我的减速器操作不正确。

我的问题是,我的 reducer 在向 API 发送 post 请求时返回 undefined。

这里是文件。如果文件丢失,请给我反馈,我会立即更新帖子。

我可以毫无问题地使用 fetchEntry 获取条目,我可以使用 deleteEntry 删除条目,更新条目的 post 请求将成功发送到 API 并且条目得到更新,但减速器不会被告知这个成功的动作并返回 undefined...

// redux/actions/entry.js
import axios from 'axios';

export const FETCH_ENTRY = 'fetch_entry';
export const CREATE_ENTRY = 'create_entry';
export const UPDATE_ENTRY = 'update_entry';
export const DELETE_ENTRY = 'delete_entry';
export const ERROR_ENTRY = 'error_entry';

const ROOT_URL  = 'http://localhost:8080/api';

// **This is the important part here**
export function updateEntry(type, data, callback) 
    return async (dispatch) =>         
        try 
            const request = axios.post(
                `$ROOT_URL/$type/edit/$data.id`,
                data.formData
            ).then(() => callback());

            dispatch( type: UPDATE_ENTRY, payload: request );
         catch(error) 
            console.log(error);
        
    


// Not defined, tbd
export function createEntry(type, data, history) 
    


// **Everything else is working fine**
export function fetchEntry(type, id, history) 
    return async (dispatch) => 
        try 
            const request = await 
            axios.get(`$ROOT_URL/$type/get/$id`);
            dispatch( type: FETCH_ENTRY, payload: request );
         catch(error) 
            history.push('/');
        
    ;


export function deleteEntry(type, id, callback) 
    return async (dispatch) => 
        try 
            const request = 
                axios.delete(`$ROOT_URL/$type/delete/$id`)
                .then(() => callback());
            dispatch( type: DELETE_ENTRY, payload: request );
         catch(error) 
            console.log(error);
        
    
 

我的reducer定义如下:

 

// redux/recuders/reducer_entry.js 
import  CREATE_ENTRY, FETCH_ENTRY, DELETE_ENTRY, UPDATE_ENTRY  from 
'../actions/entry';

export default function(state = , action) 
    switch (action.type) 
    case CREATE_ENTRY:
        return action.payload.data;
    case DELETE_ENTRY:
        return action.type;
    case FETCH_ENTRY:
        return action.payload.data;
    case UPDATE_ENTRY:
        console.log(action);
        return action.payload.data;
    default:
        return state;
    

触发发送post请求的“调用”点:

// EditEntry.js
  
this.props.updateEntry('type', data, () => 
            console.log("Successfully saved!");
            console.log(this.props);
);

我的商店是这样定义的...

// store.js
import  compose, createStore, applyMiddleware  from 'redux';
import  createBrowserHistory  from 'history';
import  syncHistoryWithStore  from 'react-router-redux';
import  createLogger  from 'redux-logger';
import thunk from 'redux-thunk';

import rootReducer from './redux/reducers';

const middleware = [
    createLogger(),
    thunk
];

const enhancers = compose(
    applyMiddleware(...middleware),
    window.devToolsExtension ? window.devToolsExtension() : f => f
)

// Create store
const store = createStore(
    rootReducer,
    ,
    enhancers
);

export const history = syncHistoryWithStore(createBrowserHistory(), 
store);

const createStoreWithMiddleware = applyMiddleware(thunk)(createStore);


export  createStoreWithMiddleware ;

并像这样给应用程序..

// index.js

import React from 'react';
import ReactDOM from 'react-dom';
import  Provider  from 'react-redux';
import Routes from './Routes';
import registerServiceWorker from './registerServiceWorker';

import reducers from './redux/reducers';

import  createStoreWithMiddleware  from './store';

const store = createStoreWithMiddleware(reducers);

ReactDOM.render(
    <Provider store=store>
        <Routes />
    </Provider>, 
    document.getElementById('root')
);
registerServiceWorker();

最后,reducers/index.js(其中 combineReducers 被调用):

// redux/reducers/index.js

import  combineReducers  from 'redux';
import  routerReducer  from 'react-router-redux';
import EntryReducer from './reducer_entry';
import  reducer as FormReducer  from 'redux-form';

const rootReducer = combineReducers(
    routing: routerReducer,
    entry: EntryReducer,
    form: FormReducer
);

export default rootReducer;

也许你们中的某个人可以帮助解决这个问题?

【问题讨论】:

【参考方案1】:

好的。非常感谢@SALEH:现在明白了!

这是解决方案:)

export function updateEntry(type, data, callback) 
    return async (dispatch) =>         
        try 
            await axios.post(`$ROOT_URL/$type/edit/$data.anlageID`, data.formData)
                .then((response) => 
                    dispatch( type: UPDATE_ENTRY, payload: response ); 
                    callback()                   
                );
         catch(error) 
            console.log(error);
        
    

【讨论】:

【参考方案2】:

不会返回来自then 块的任何内容

// **This is the important part here**
export function updateEntry(type, data, callback) 
    return async (dispatch) =>         
        try 
            const request = axios.post(
                `$ROOT_URL/$type/edit/$data.id`,
                data.formData
            ).then(() => callback());

            dispatch( type: UPDATE_ENTRY, payload: request );
         catch(error) 
            console.log(error);
        
    

【讨论】:

我不明白。我在 then 块内调用定义的回调。看看这个EditEntry.jsthis.props.updateEntry('type', data, () =&gt; console.log("Successfully saved!"); console.log(this.props); ); 我想我现在卡住了。当我想获得POST-Requestresponse 时,我应该在then-Block 中返回什么?

以上是关于Reducer 返回未定义(Redux-Thunk 和 Promise)的主要内容,如果未能解决你的问题,请参考以下文章

未处理的拒绝(错误)reducer 返回未定义

给定动作“LoadEntries”,reducer“entries”返回未定义。

尽管向 createStore() 提供了 initialState,为啥我得到“Reducer [...] 在初始化期间返回未定义”?

redux-thunk的理解

为啥我的 Redux reducer 认为我的状态是未定义的?

使用 Redux-thunk 调用操作不起作用