React + Axios:Uncaught TypeError:无法读取属性'键入'未定义的 - >我承诺的事情并没有加起来

时间:2017-03-25 20:11:01

标签: api reactjs promise axios

我使用以下内容:

  • " axios":" ^ 0.15.3"
  • "反应":" ^ 15.4.2"
  • " react-redux":" ^ 5.0.3"
  • " redux":" ^ 3.6.0"
  • " redux-immutable":" ^ 3.1.0"

我想从波士顿市的数据门户网站上搜索数据。我的目标是当一个人进入" Property"屏幕,该组件的ComponentWillMount()将调用一个sychronous API调用,以在呈现compnonet之前检索数据。请注意我将所有这些与redux-saga同步工作,但就像我上面提到的那样,用户操作会在数据显示在组件中之前触发数据的恢复。

我的代码出现以下错误:

  

未捕获的TypeError:无法读取属性'键入'未定义的

这是我到目前为止所拥有的:

  1. 在我的property.js中(我删除了与错误无关的代码):
  2. //External Dependencies
    import { connect } from "react-redux";
    
    //Internal Dependencies
    import { requestCityBosAPI } from "../../actions/citybosapi_action";
    
    class Property extends React.Component {
      constructor(props) {
        super(props);
      };
    
      componentWillMount() {
        if (this.props.selectedAccount) {
          const citybosPID=this.props.selectedAccount.toJS().citybos_pid;
          console.log('Inside componentWillMount with citybospid=[' +citybosPID +"]");
          this.props.requestCityBosAPI(citybosPID);
        }
      };
    
    ...
    
    Property.propTypes = {
      accounts: React.PropTypes.array.isRequired,
      selectedAccount: React.PropTypes.object
    };
    
    export default connect(
      state => ({
        accounts: state.get('accounts').get('json').get('accounts').toJS(),
        selectedAccount: state.get('accounts').get('selectedAccount')
      }),
      { requestCityBosAPI }
    )(Property)
    
    1. 在我的citybosapi_action中,我有:
    2. //External Dependencies
      import axios from 'axios';
      
      //Internal Dependencies
      import * as actionTypes from './action_types';
      
      export function requestCityBosAPI(citybosPID) {
          let newcitybosPID='1000001021';
          // console.log('requestCityBosAPI citybosPID=[' + citybosPID + "]");
          const request = >   axios.get(`https://data.cityofboston.gov/resource/ti2c-bzzp.json?$where=PID=\"` + newcitybosPID + `\"`)
            .then(response => {
              console.log(response);
              if (response.status === 200) {
                return {
                  type: actionTypes.OK_CITYBOSAPI,
                  property2017: response.data,
                  createDT: new Date().toUTCString()
             }
           }
         })
      
           

      }

      1. 我的citybos_reducer,我有:
      2.    //External Dependencies
           import Immutable from 'immutable';
        
           //Internal Dependencies
           import * as actionTypes from '../actions/action_types';
        
           const initialState = Immutable.Map({
             property2017: null,
             createDT: null,
             error: null,
             errorDT: null
           });
        
          console.log(initialState);
        
           export default (state = initialState, action) => {
             console.log(action);
             console.log("action.type=[" +action.type +"]");
             if (action.type === actionTypes.OK_CITYBOSAPI) {
                return state.merge({ //returning new states
                  property2017: action.property2017,
                  createDT: action.createDT
                 })
             }
             else if (action.type === actionTypes.FAILED_CITYBOSAPI) {
               console.log('FAILED_CITYBOSAPI ' + new Date().toUTCString());
               return state.merge({ //returning new state
                 error: action.error,
                 errorDT: action.errorDT
               })
             }
        
             return state; //returns initial state
           }
        

        在Chrome控制台中,我得到: enter image description here

        您可以看到错误,然后我就会将正确的数据打印到控制台,但我的减速器没有任何反应。所有帮助表示赞赏。我可以看看我是否注释掉了这一行:

          

        const request =   axios.get(https://data.cityofboston.gov/resource/ti2c-bzzp.json?$where=PID=\"   + newcitybosPID + \"

        从动作到减速器一切正常......所以我觉得作为一个新手,我使用了axios错误。我甚至尝试了以下代码,并采取了相同的错误:

          export function requestCityBosAPI(citybosPID) {
            console.log('requestCityBosAPI citybosPID=[' + citybosPID + "]");
            axios.get(`https://data.cityofboston.gov/resource/ti2c-bzzp.json?$where=PID=\"` + citybosPID + `\"`)
              .then(function (response) {
                console.log(response);
                if (response.status === 200) {
                  return {
                    type: actionTypes.OK_CITYBOSAPI,
                    property2017: response.data,
                    createDT: new Date().toUTCString()
                  }
                }
                else {
                  return {
                    type: actionTypes.FAILED_CITYBOSAPI,
                    error: response.statusText,
                    errorDT: new Date().toUTCString()
                  }
                }
              })
              .catch(function (error) {
                console.log(error);
        
              });
          }
        

        感谢提前!

1 个答案:

答案 0 :(得分:0)

您的操作创建者未返回任何内容,因此undefined正在发送到您的商店。当您尝试在reducer中读取type的属性undefined时,会引发错误。

如果你看一下动作创建者:

export function requestCityBosAPI(citybosPID) {
    let newcitybosPID='1000001021';
    // console.log('requestCityBosAPI citybosPID=[' + citybosPID + "]");
    const request = >   axios.get(`https://data.cityofboston.gov/resource/ti2c-bzzp.json?$where=PID=\"` + newcitybosPID + `\"`)
      .then(response => {
        console.log(response);
        if (response.status === 200) {
          return {
            type: actionTypes.OK_CITYBOSAPI,
            property2017: response.data,
            createDT: new Date().toUTCString()
       }
     }
   })
}

然后唯一的return语句是 传递给.then()的匿名函数。

作为库的Axios只能进行同步调用 - 可以进行同步AJAX调用,但你必须问自己这是否真的是你想要的?在请求结算之前,您的应用将完全没有响应,这通常是一种糟糕的用户体验。

我会使用异步调用,如果这意味着组件没有数据的时间很短,那么您可以只渲染一段时间的加载屏幕。你可以用你喜欢的redux副作用库(redux-saga,redux-thunk等)来做到这一点。