动作必须是普通对象。使用自定义中间件进行异步操作/未定义不是对象/使用 navigator.geolocation 出现错误

Posted

技术标签:

【中文标题】动作必须是普通对象。使用自定义中间件进行异步操作/未定义不是对象/使用 navigator.geolocation 出现错误【英文标题】:Actions must be plain objects. Use custom middleware for async actions/ undefined is not an object/ Getting error using navigator.geolocation 【发布时间】:2019-03-12 15:31:45 【问题描述】:

我不断收到“未处理的拒绝(错误):操作必须是普通对象。使用自定义中间件进行异步操作。”

详细信息:我关注this tutorial 系列,但在 Windows 10 中为 android 开发。使用 react-native v0.57。 我的问题是,当我从 Home 组件调用 this.props.getCurrentLocation() 时,我得到了那个错误。似乎很多人在做同样的教程时都遇到过这个问题,所以我读了很多书,但我就是搞不明白。

这是我的代码: src/routes/Home/modules/home.js

import update from "react-addons-update";
import constants from "./actionConstants";
import  Dimensions  from "react-native";

// -------------------------------
// CONSTANTS
// -------------------------------

const  GET_CURRENT_LOCATION  = constants; // keeps all the constants in one file
const  width, height  = Dimensions.get("window");
const ASPECT_RATIO = width / height;
const LATITUDE_DELTA = 0.0922;
const LONGITUDE_DELTA = ASPECT_RATIO * LATITUDE_DELTA;

// -------------------------------
// ACTIONS
// -------------------------------

export function getCurrentLocation()
  return (dispatch)=> 
    navigator.geolocation.getCurrentPosition(
      (position) =>  
        dispatch(
          type:GET_CURRENT_LOCATION,
          payload:position
        ); 
      ,
      (error) => 
          console.warn("error::" . error.code);
          var msg = null;
          switch(error.code) 
            case error.PERMISSION_DENIED:
                // msg = "User denied the request for Geolocation.";
                msg = "Usuario denego la solicitud de Geolocalizacion.";
                break;
            case error.POSITION_UNAVAILABLE:
                msg = "Location information is unavailable.";
                break;
            case error.TIMEOUT:
                msg = "The request to get user location timed out.";
                break;
            case error.UNKNOWN_ERROR:
                msg = "An unknown error occurred.";
                break;
          
          alert(msg);
      ,
       enableHighAccuracy: true, timeout: 8000, maximumAge: 10000 
    );
  




// -------------------------------
// ACTION HANDLERS
// -------------------------------

function handleGetCurrentLocation(state, action)
  return update(state, 
    region:
      latitude:
        $set:action.payload.coords.latitude
      ,
      longitude:
        $set:action.payload.coords.longitude
      ,
      latitudeDelta:
        $set:LATITUDE_DELTA
      ,
      longitudeDelta:
        $set:LONGITUDE_DELTA
      
    
  );



const ACTION_HANDLERS = 

  GET_CURRENT_LOCATION:handleGetCurrentLocation
;

const initialState = 
  region:
;

export function HomeReducer (state = , action) 
  const handler = ACTION_HANDLERS[action.type];
  return handler ? handler(state, action) : state;
;

src/routes/Home/modules/actionConstants.js

export default 
  GET_CURRENT_LOCATION: "GET_CURRENT_LOCATION"
;

src/routes/home/containers/HomeContainer.js

import  connect  from "react-redux";
import Home from "../components/Home";
import 
  getCurrentLocation
 from "../modules/home";

const mapStateToProps = (state) => (
  region:state.home.region
);

const mapActionCreators =  
  getCurrentLocation 
; 

export default connect(mapStateToProps, mapActionCreators)(Home);

app/src/main/AndroidManifest.js

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.taxiapp">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

src/store/createStore.js

import  createStore, applyMiddleware, compose  from "redux";
import thunk from "redux-thunk";
import makeRootReducer from "./reducers";
import  createLogger  from "redux-logger";

const log = createLogger( diff: true, collapsed: true );

// Export function that can create our store and autopersist the data

export default (initialState = ) => 

  // Middleware configuration
  const middleware = thunk, log; 

  // Store enhancers
  const enhancers = [];

  // Store instantiation
  const store = createStore(
    makeRootReducer(),
    initialState,
    compose(
      applyMiddleware(...middleware),
      ...enhancers
    )
  );
  return store;
;

src/routes/home/components/Home.js

// Takes care of the state
import React from "react";
import  View, Text  from "react-native";

import Container from "native-base";
import MapContainer from "./MapContainer";

class Home extends React.Component 

  componentDidMount() 

    this.props.getCurrentLocation();

  
  render()

    return(
      <Container>
           this.props.region.latitude && 
          <MapContainer region= this.props.region/>
         
      </Container>
    );

  


export default Home;

【问题讨论】:

【参考方案1】:

错误似乎在商店实例化中。

// Store instantiation
  const store = createStore(
    makeRootReducer(),
    initialState,
    compose(
      // applyMiddleware(...middleware), => works after commenting this line
      applyMiddleware(thunk),
      ...enhancers
    )
  );

【讨论】:

以上是关于动作必须是普通对象。使用自定义中间件进行异步操作/未定义不是对象/使用 navigator.geolocation 出现错误的主要内容,如果未能解决你的问题,请参考以下文章

如何修复'动作必须是普通对象。使用自定义中间件进行异步操作。

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

Redux 错误操作必须是普通对象。使用自定义中间件进行异步操作

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

动作必须是普通对象。使用自定义中间件

动作必须是普通对象。将自定义中间件用于测试库而不是应用程序上的异步操作