使用redux-thunk创建未定义的错误,而Promise工作得很好

时间:2018-02-05 14:45:37

标签: javascript react-redux redux-thunk redux-promise

这是我的减速机:

export default function(state=[], action){
    switch (action.type) {
        case FETCH_PLACES: 
            return [action.payload.data]; 
    }
    return state;
}

这是我的飞行箱:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import moment from 'moment';

class FlightList extends Component {

    renderFlights(flightData){
        const result = flightData.data.length;     
        console.log(flightData);  
        var rows = [];
        for (var i = 0; i < result; i++) {
            rows.push(
            <tr key={i} >
                <td>{i+1}</td>,
                <td>{flightData.data[i].airlines[0]}</td>,
                <td>{flightData.data[i].route[0].flight_no}</td>,
                <td>{flightData.data[i].mapIdfrom}</td>,
                <td>{flightData.data[i].mapIdto}</td>,
                <td>
                    {
                        moment.unix(flightData.data[i].dTime).format("YYYY-MM-DD HH:mm")
                    }
                </td>,
                <td>
                    {
                        moment.unix(flightData.data[i].aTime).format("YYYY-MM-DD HH:mm")
                    }
                </td>,
                <td>{flightData.data[i].conversion.EUR} Euro</td>
            </tr>
            );
        }
        return <tbody>{rows}</tbody>;
    }   

    render(){
        return (
            <table className="table table-hover">
                <thead>
                    <tr>
                        <th>#</th>
                        <th>Airline</th>
                        <th>Flight Number</th>
                        <th>From</th>
                        <th>To</th>
                        <th>Departure</th>
                        <th>Arrival</th>
                        <th>Cost</th>
                    </tr>
                </thead>
                    {this.props.flights.map(this.renderFlights)}
            </table>
        );
    }
}

const mapStateToProps=({ flights })=>{
    return { flights };
};

export default connect(mapStateToProps)(FlightList);

在我尝试运行应用程序时使用redux-thunk后,出现以下错误:

  

未捕获的TypeError:无法读取未定义的属性“数据”

我试图找出造成这种情况的原因,如果在我的reducer中我将[action.payload.data]更改为[action.payload],那么我会收到错误:

  

未捕获的TypeError:无法读取未定义的属性“长度”

这是我的src / index.js:

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

//import ReduxPromise from 'redux-promise';
import thunk from 'redux-thunk';


import App from './components/app';
import reducers from './reducers';

//const createStoreWithMiddleware = applyMiddleware(ReduxPromise)(createStore);
const store = createStore(reducers,applyMiddleware(thunk));

ReactDOM.render( 
  <Provider store={store}> 
  <App /> 
  </Provider> 
  , document.querySelector('.container'));

但无论我总是得到一个包含我需要的所有信息的JSON文件,并且在我的容器中我尝试将它们发布在表格中。 我没有得到导致这种情况的原因。有没有办法解决这个问题,而不是将我的源文件更改为以前的文件?

更新

import axios from 'axios';
import moment from 'moment';

const ROOT_URL = `https://api.skypicker.com/flights`;

//to keep out action type consistent between our action creator and our action reducers
export const FETCH_PLACES = 'FETCH_PLACES';

export function createQueryString(obj){
    const Qstring = require('querystring'); 
    const newQuery = Qstring.stringify(obj);
    return newQuery;
}

export function fetchPlaces(query) {

    let skypicker = {
        flyFrom: query.from,
        //to: query.to,
        dateFrom: query.startDate,
        dateTo: query.finishDate,
        price_to: query.budget,
        partner: "picky"
        //partner_market: "yout id"
    };

    const FormattedDateFrom = moment(skypicker.dateFrom).format('DD/MM/YYYY');
    const FormattedDateTo = moment(skypicker.dateTo).format('DD/MM/YYYY');
    skypicker.dateFrom = FormattedDateFrom;
    skypicker.dateTo = FormattedDateTo;

    const queryString = createQueryString(skypicker);
    const url = `${ROOT_URL}?${queryString}`;
    const request = axios.get(url);

    return {
        type: FETCH_PLACES, 
        payload: request
    };

}

1 个答案:

答案 0 :(得分:1)

您没有包含您的动作创建者。问题在于你使用redux-thunk的方式。

  1. 您在组件/容器中调度操作
  2. 如果调度的动作返回功能,那么redux-thunk将会 执行该功能
  3. 在该函数内部,您必须调度另一个将返回对象的操作(类型和从API获取的数据)
  4. 修改

    此代码段应该可以完成这项工作。如果一切顺利,您只需将fetchPlaces动作创建者替换为我的fetchPlaces动作创建者。

    export function fetchPlaces(query) {
      // This is your thunk because we are not retuning object but a function redux-thunk will execute this function
      return function(dispatch) {
        const skypicker = {
          flyFrom: query.from,
          dateFrom: query.startDate,
          dateTo: query.finishDate,
          price_to: query.budget,
          partner: 'picky',
        }
    
        const FormattedDateFrom = moment(skypicker.dateFrom).format('DD/MM/YYYY')
        const FormattedDateTo = moment(skypicker.dateTo).format('DD/MM/YYYY')
        skypicker.dateFrom = FormattedDateFrom
        skypicker.dateTo = FormattedDateTo
    
        const queryString = createQueryString(skypicker)
        const url = `${ROOT_URL}?${queryString}`
        axios.get(url).then(function(response) {
          // If request was successful you want to dispatch new action
          dispatch({
            type: FETCH_PLACES,
            payload: response,
          })
        })
      }
    }