簡體   English   中英

使用redux-thunk時動作必須是普通對象

[英]Actions must be plain objects while using redux-thunk

我正在使用react-redux和redux-thunk實現異步動作創建者。 但是,我收到以下錯誤消息:未捕獲的錯誤:操作必須是普通對象。 使用自定義中間件進行異步操作。

我知道動作應該是普通的對象,而像thunk這樣的中間件應該負責處理不是它們的情況。 我已經閱讀了幾本教程,並研究了在此上可以找到的每個 SO問題,但是我仍然無法弄清楚哪里出了問題。 我是否錯誤地設置了thunk,或者我以錯誤的方式使用動作創建者? 這可能是webpack或其他錯誤嗎?

在下面,我包括了我認為相關的代碼片段。 請讓我知道是否需要其他信息。

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { Route } from 'react-router';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';

import rootReducer   from './reducers';
import Layout    from './components/Layout.js';
import OrderPage from './containers/order-page';


const store = createStore(
    rootReducer,
    applyMiddleware(thunk)
    );

ReactDOM.render(
    <Provider store={store}>
        <App>
            <Route  exact path="/" component={Layout}/>
        </App>
    </Provider>,
    document.querySelector('.app'));

reducers / order.js

import { FETCH_ERR, FETCH_SUCCESS, START_FETCH } from '../actions/types';

const initialState = {
  fetching: false
};

export default (state=initialState, action)=>{
  switch (action.type) {
    case START_FETCH: 
      return {
        fetching: true
      }
    case FETCH_ERR:
      return {
        err: action.payload.err,
        fetching: false
      }
    case FETCH_SUCCESS:
      return {
        price: action.payload,
        fetching: false
      }
    default:
        return state
  }

}

動作/price-fetch.js

import axios from 'axios'

const FETCH_ERR = 'FETCH_ERR'
const FETCH_SUCCESS = 'FETCH_SUCCESS'
const START_FETCH  = 'START_FETCH'


const fetchSucc = (data)=>{
  return{
    type:FETCH_SUCCESS,
    payload:data
  }
}

const fetchFail = (message)=>{
  return{
    type:FETCH_ERR,
    payload:message
  }
}

const startFetch = () =>{
  return{
    type: START_FETCH,
    payload:null
  }
}

const fetchPrices = () =>{
  return async (dispatch) =>{
    try {
      dispatch(startFetch())
      let data = await axios.get('mybackendurl')
      dispatch(fetchSucc(data))
    } catch (error) {
      dispatch(fetchFail({err:'failed to get shit'}))
    }
  }
}

export {
    FETCH_ERR,
    FETCH_SUCCESS,
    fetchPrices,
    START_FETCH
}

相關的容器/order.js

import React, { Component }     from 'react';

import { connect }                      from 'react-redux';

import { fetchPrices }          from '../actions/price-fetch';

class Order extends Component {


...



  render() {
    this.props.fetchPrices();
    return ...

  }


const mapDispatchToProps = dispatch => {
  return {
    fetchPrice: () => {
      dispatch(fetchPrices())
    }
  }
}

function mapStateToProps(state){
    return {
        prices: state.order
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(Order);

在此先感謝您的幫助!

如果有人遇到相同的問題。 問題不在於上面顯示的代碼,也不在於我如何調度動作。 我在另一個文件中有一個關於redux-store的重復定義,這用中間件覆蓋了該定義。

如果有人在使用ImmutableJS + Typescript時不知所措,那么事實證明您必須為實際應用的中間件定義“ initialState”。

export const store = createStore(
  combineReducers({APIReducer}),
  {},
  applyMiddleware(thunk.withExtraArgument(api))
);

我懷疑這可能是因為您具有async (dispatch)功能。 那將導致它返回一個Promise ,這甚至可能使thunk感到困惑。

在正常情況下,函數本身將返回另一個函數, thunk將注入dispatch並再次調用,您將在函數內部調用dispatch

arg => dispatch => dispatch({ type: arg });

當您添加async ,它基本上與此相同:

arg => dispatch => Promise.resolve(dispatch({ type: arg }));

您可能不得不在其中拋棄async/await ,而只是將axios用作常規Promise ,或添加一些額外內容以確保它不返回任何內容而不是Promise

const fetchPrices = () =>{`
 return async (dispatch) =>{`
 try {
   dispatch(startFetch())
   let data = await axios.get('mybackendurl')
   dispatch(fetchSucc(data))
 } catch (error) {
   dispatch(fetchFail({err:'failed to get shit'}))
  }
 }
}

回報了承諾,所以當你這樣做

const mapDispatchToProps = dispatch => {
       return {
    fetchPrice: () => {
      dispatch(fetchPrices())
    }
  }
}

dispatch(fetchPrices())獲得了一個承諾,而不是一個普通的對象

我做這些事情的方式是讓我沉重的行動; 調用async,當解析的調度數據要存儲並在您的組件中偵聽並處理數據(價格表)更改時。

const mapDispatchToProps = dispatch => {
  return {
    fetchPrice
  }
}

因此,當價格表為空且承諾未解決/被拒絕時,您可以顯示“正在加載,請稍候”

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM