为什么我的异步react-redux动作没有返回一个对象

时间:2018-05-22 20:26:02

标签: reactjs react-redux redux-thunk

我还是React-Redux的新手。

我正在构建一个单页React-Redux应用程序,用于搜索Zillow API并返回一个列表,以及3个'Comps'(可比属性)。在结果中,会显示该属性的缩略图(由Google的Geolocation API和Google Street Views API提供)。

因此,一个事件总共有4个API调用:用户在搜索框中输入一个地址:

1)用户输入地址:调用Geolocate API以自动填充地址。 2)用户执行地址搜索:地址字符串被传递给Google Street Views API,后者返回缩略图。 3)用户执行地址搜索:地址字符串调用Zillow API获取该列表的结果。 4)然后将列表结果用作调用'GetComps'API的参数。

我已经开发了所有工作,除了下面的错误在我部署到我的登台/生产环境后出现。我正在部署无服务器后端(www.turbo360.co)。

我的github回购:https://github.com/ScorpIan555/thrillow

我将下面的操作包装起来,导致thunk dispatch()函数出错,它应该返回一个对象。我已经阅读了文档和很多SO问题,并且在很多很多小时后都看不到我的错误。任何帮助表示赞赏。谢谢!

Error Message:

导致错误的操作:

dispatchLatLngFromSearchBoxToStore: (latLngFromGeocodeApi) => {
    console.log('dispatchLatLngFromSearchBoxToStore ', latLngFromGeocodeApi)
    return dispatch => {
        return dispatch({
            type: constants.LAT_LONG_RECEIVED_FROM_SEARCH_BOX,
            data: latLngFromGeocodeApi
        })
    }
}

以下是调度操作的组件: https://github.com/ScorpIan555/thrillow/blob/master/src/components/containers/LandingPage.js

import React, { Component } from 'react'
import PlacesAutocomplete, { geocodeByAddress, getLatLng } from 'react-places-autocomplete'
import actions from '../../actions'
import { connect } from 'react-redux'
import { LocationSearchInput } from '../containers'

class LandingPage extends Component {
  constructor() {
    super()
    this.state = {
      // Initialize component with address string utilized in Google Geolocate API
      address: '',
      // Initialize component with latLng object which stores latitude and longitude results from Geolocate API
      latLng: {}
    }
  }

  onButtonClick(address, event) {
    // event.preventDefault()
    console.log('Address Search Executed.event :', event)
    console.log('Address Search Executed!', address)



    this.handleSelect(address)
  }


      // Handle change for controlled component
      handleChange(address) {

        this.setState({ address })
        // Log state change
        console.log(JSON.stringify(this.state.address))
        console.log(JSON.stringify(address))
  }

  // Handle user input to search box
  handleSelect(address) {
    (address == 'null') ? address = this.state.address : address
    console.log('address: ', address)
    console.log('typeof(address):', typeof(address))

//调用Google Maps Geolocator API,返回一个带有lat / lng属性的对象

geocodeByAddress(address)
      .then(results => getLatLng(results[0]))
       // Simulatneously, asynchronously call both the dispatchToStore & the Zillow API call
      .then(latLng => this.addressCalls(latLng, address))
      .catch(error => console.error('Error', error))
  }

  // 1) Dispatch coordinates from Google Geolocate API to store for use in client
  // 2) Dispatch call to Zillow API thru the back-end
  addressCalls(latLng, address) {
    console.log('addressCalls.latLng: ', latLng)
    console.log('addressCalls.address: ', address)
    // Send coordinates from Geolocate API to store asynchronously thru Redux
    this.props.dispatchLatLngFromSearchBoxToStore(latLng)

    // Split address from search box for input into Zillow API
    const paramsAddress = address.split(',', 1)
    // Split citystatezip from search box for input into Zillow API
    const arrayFromAddressAndCitystatezip = address.split(',')
    const paramsCitystatezip = arrayFromAddressAndCitystatezip[1] + ',' + arrayFromAddressAndCitystatezip[2]
    // Store Zillow API parameters in client, to be passed into back-end
    var params = {
      address: paramsAddress,
      citystatezip: paramsCitystatezip
    }
    // Call Zillow 'GetSearchResults' API, return listing results
    this.props.getZillowListingResults(params)
      .then(listingResults => {
        // Capture parameters needed to call Zillow 'GetComps' API, return comp results
        params.zpid = listingResults.body.data.response.results.result[0].zpid[0]
        // Set required parameter 'count'
        params.count = 3
        // Call Zillow 'GetComps' API, return comp results


this.props.getZillowCompsResults(params)
      })

  }

  render() {

const addressValue = this.state.address
const addressValueType = typeof(this.state.address)
console.log('addressValue: ', addressValue)
console.log('addressValueType: ', addressValueType)
console.log('props:  ', this.props)

return(
  <section className="bg-dark text-white space-xlg">

      <img alt="Image" src="dist/assets/img/laith-abdulkareem-96120-unsplash.jpg" className="bg-image opacity-40" />
      <div className="container">
          <div className="row text-center justify-content-center section-intro">
              <div className="col-12 col-md-10 col-lg-8">
                  <h1 className="display-3">Welcome to Thrillow</h1>
                  <span className="lead">A Zillow Knockoff... And not even the good kind!</span>
              </div>

          </div>

          <div className="row text-center ">
              <div className="col">
                  <a href="#" className="btn btn-outline-secondary mb-1 text-white opacity-80">BUY</a>
                  <a href="#" className="btn btn-outline-secondary mb-1 text-white">RENT</a>
                  <a href="#" className="btn btn-outline-secondary mb-1 text-white">SELL</a>
                  <a href="#" className="btn btn-outline-secondary mb-1 text-white">ZESTIMATE</a>
              </div>

          </div>

          <div className="row justify-content-center">
              <div className="col-12 col-md-10 col-lg-8">
                  <div className="card card-sm">
                      <div className="card-body row no-gutters align-items-center">

                          <LocationSearchInput value={addressValue} onChange={this.handleChange.bind(this)} onSelect={this.handleSelect.bind(this)} onClick={this.onButtonClick.bind(this, addressValue)} className="form-control form-control-lg form-control-borderless" type="search" placeholder="Search topics or keywords" />

                      </div>
                  </div>
              </div>

          </div>

      </div>

  </section>
)

}
}

const stateToProps = (state) => {

}

const dispatchToProps = (dispatch) => {
    return {
    // Dispatch Zillow 'GetSearchResults' API call to '/homes' route
    getZillowListingResults: (params) => dispatch(actions.getZillowListingResults(params)),
    // Dispatch Zillow 'GetSearchResults' API call to '/comps' route
    getZillowCompsResults: (params) => dispatch(actions.getZillowCompsResults(params)),
    // Dispatch latLng object returned from Google Maps Geolocate API call to store
    dispatchLatLngFromSearchBoxToStore: (latLng) => dispatch(actions.dispatchLatLngFromSearchBoxToStore(latLng))
    }
}

export default connect(stateToProps, dispatchToProps)(LandingPage)

商店: https://github.com/ScorpIan555/thrillow/blob/master/src/stores/index.js

import { createStore, applyMiddleware, combineReducers } from 'redux'
import thunk from 'redux-thunk'
import { userReducer, listingReducer, compsReducer } from '../reducers'

var store
export default {

configure: (initialState) => { // initialState can be null

    const reducers = combineReducers({ // insert reducers here
        user: userReducer,
        listing: listingReducer,
        comps: compsReducer
    })

    if (initialState){
        store = createStore(
            reducers,
            initialState,
            applyMiddleware(thunk)
        )

        return store
    }

    store = createStore(
        reducers,
        applyMiddleware(thunk)
    )

    return store
},

currentStore: () => {
    return store
}
}

1 个答案:

答案 0 :(得分:0)

我正在关闭这个,我没有得到回复,最后在解决方案上乱哄哄地继续推进项目。当我需要重新审视这个主题时,我会改写并重新询问是否需要。

我做过的一个错误就是存在,需要修复的是我的动作创建者中有console.logs被标记。