Redux-Thunk:动作必须是普通对象。使用自定义中间件进行异步操作

时间:2018-05-01 08:23:07

标签: android react-native redux redux-thunk

使用react-native和redux-thunk无法解决此问题。

我正在尝试将数据发布到firebase.io并反复出现相同的错误:操作必须是普通对象。使用自定义中间件进行异步操作。

减速器/ index.js

import { createStore, combineReducers, compose, applyMiddleware } from 'redux';
import thunk from 'redux-thunk'
import PlacesReducer from './placesReducer'


const rootReducer = combineReducers({
  places : PlacesReducer,
    });

let composeEnhancers = compose;

if (__DEV__) {
    composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
}

const configureStore = () => {
    return createStore(rootReducer, applyMiddleware(thunk));
};

export default configureStore;

动作/ index.js

export const addPlace = (placeName, location, image) => {
    return dispatch => {
        const placeData = {
            name: placeName,
            location: location
        };
        fetch("https://awesome-places-b592c.firebaseio.com/placesReducer.json", {
            method: "POST",
            body: JSON.stringify(placeData)
        })
        .catch(err => console.log(err))
        .then(res => res.json())
        .then(parsedRes => {
            console.log(parsedRes);
        });
    };
};

减速器/ placesReducer.js

const initialState = {
  places: []
};

const reducer = (state = initialState, action) => {
  switch (action.type) {
    case "ADD_PLACE":
      return {
        ...state,
        places: state.places.concat({
          key: Math.random(),
          name: action.placeName,
          image: {
            uri: action.image.uri,
            location: action.location
          }
        })
      };
    default:
      return state;
  }
};

export default reducer;

感谢所有帮助,谢谢。

更新

在reducers / index.js

中为createStore()函数添加了initialState参数
const configureStore = () => {
  return createStore(rootReducer, {places: []}, applyMiddleware(thunk));
};

仍然收到相同的错误

2 个答案:

答案 0 :(得分:0)

异步请求完成后,您需要dispatch操作

.then(parsedRes => {
     console.log(parsedRes);
     dispatch({
       type: YOUR_REDUCER_TYPE,
       parsedRes
    })
});

同样如createStore docs中所述,您需要添加initialState

(reducer, preloadedState, enhancer)

答案 1 :(得分:0)

尝试按如下方式更新代码:

export const addPlace = (placeName, location, image) => {
    //return dispatch => {
        const placeData = {
            name: placeName,
            location: location
        };
        fetch("https://awesome-places-b592c.firebaseio.com/placesReducer.json", {
            method: "POST",
            body: JSON.stringify(placeData)
        })
        .catch(err => console.log(err))
        .then(res => res.json())
        .then(parsedRes => {
            console.log(parsedRes);
            // you may tweak this
            // use ...parsedRes following the reducer code you paste,
            // I assume location, placeName and image are inside parsedRes
            dispatch({ type:"ADD_PLACE", ...parsedRes })
        });
    //};
};

然后在减速器中:

const reducer = (state = initialState, action) => {
  switch (action.type) {
    case "ADD_PLACE":
      // check the action content
      console.log(action)
      return {
        ...state,
        places: state.places.concat({
          key: Math.random(),
          name: action.placeName,
          image: {
            uri: action.image.uri,
            location: action.location
          }
        })
      };
    default:
      return state;
  }
};