使用 redux-thunk 会产生未定义的错误,而 Promise 工作正常
using redux-thunk creates undefined error while Promise work just fine
这是我的减速器:
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
之后,我收到以下错误:
Uncaught TypeError: Cannot read property 'data' of undefined
我试图弄清楚是什么原因造成的,如果我在我的减速器上将 [action.payload.data]
更改为 [action.payload]
然后我得到错误:
Uncaught TypeError: Cannot read property 'length' of undefined
这是我的 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 文件,其中包含我需要的所有信息,并且在我的容器中我尝试以 table 格式发布它们。
我不明白是什么原因造成的。有什么办法可以解决这个问题而不用把我的源文件改成原来的样子吗?
更新
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
};
}
您没有包括您的动作创作者。问题在于您使用 redux-thunk 的方式。
- 您在 component/container
中调度操作
- 如果调度的动作returns函数那么redux-thunk将会
执行那个函数
- 在该函数中,您必须分派另一个操作,该操作将 return 一个对象(类型和您从 API 获得的数据)
编辑:
这段代码应该可以完成工作。如果一切顺利,您应该用我的 fetchPlaces
action creator 替换您的 fetchPlaces
action creator。
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,
})
})
}
}
这是我的减速器:
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
之后,我收到以下错误:
Uncaught TypeError: Cannot read property 'data' of undefined
我试图弄清楚是什么原因造成的,如果我在我的减速器上将 [action.payload.data]
更改为 [action.payload]
然后我得到错误:
Uncaught TypeError: Cannot read property 'length' of undefined
这是我的 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 文件,其中包含我需要的所有信息,并且在我的容器中我尝试以 table 格式发布它们。 我不明白是什么原因造成的。有什么办法可以解决这个问题而不用把我的源文件改成原来的样子吗?
更新
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
};
}
您没有包括您的动作创作者。问题在于您使用 redux-thunk 的方式。
- 您在 component/container 中调度操作
- 如果调度的动作returns函数那么redux-thunk将会 执行那个函数
- 在该函数中,您必须分派另一个操作,该操作将 return 一个对象(类型和您从 API 获得的数据)
编辑:
这段代码应该可以完成工作。如果一切顺利,您应该用我的 fetchPlaces
action creator 替换您的 fetchPlaces
action creator。
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,
})
})
}
}