我正在构建一个使用自己的API的应用程序。 (正在为其运行nodejs服务器),无论如何,动作创建者都会将成功的actionCreator传递给reducer。
这是我的提取操作创建者:
export function fetchData() {
return dispatch => {
dispatch(fetchBegin());
return fetch('/api/selectAll')
.then(handleErrors)
.then(res => res.json())
.then(json => {
dispatch(fetchSuccess(json));
return json;
})
.catch(error => dispatch(fetchFailure(error)));
};
}
这是“ index.js”操作中的其他功能
// Handle HTTP errors since fetch won't.
function handleErrors(response) {
if (!response.ok) {
throw Error(response.statusText);
}
return response;
}
export const fetchBegin = () => ({
type: FETCH_DATA_BEGIN
});
export const fetchSuccess = data => ({
type: FETCH_DATA_SUCCESS,
payload: data
});
export const fetchFailure = error => ({
type: FETCH_DATA_FAILURE,
payload: error
});
这是我的travelReducer,我已经在文件顶部导入了操作类型
const initialState = {
items: [],
loading: false,
error: null
};
export default function travelReducer(state = initialState, action) {
console.log('action :', action.type);
switch (action.type) {
case FETCH_DATA_BEGIN:
// Mark the state as "loading" so we can show a spinner or something
// Also, reset any errors. We're starting fresh.
return {
...state,
loading: true,
error: null
};
case FETCH_DATA_SUCCESS:
// All done: set loading "false".
// Also, replace the items with the ones from the server
return {
...state,
loading: false,
items: action.payload
};
case FETCH_DATA_FAILURE:
console.log('failure should be hit');
// The request failed, but it did stop, so set loading to "false".
// Save the error, and we can display it somewhere
// Since it failed, we don't have items to display anymore, so set it empty.
return {
...state,
loading: false,
error: action.payload,
items: []
};
default:
// ALWAYS have a default case in a reducer
return state;
}
}
然后我在travelList容器中使用它。我还导入了fetchTravel()函数,并在componentDidMount()上调用this.props.fetchTravel()
const mapStateToProps = state => ({
data: state.travel.items,
loading: state.travel.loading,
error: state.travel.error
});
// // anything returned from this func will end up as props
// // on this container (this.props.fetchTravelData)
function mapDispatchToProps(dispatch) {
// whenever fetchTravelData is called, the result should be passed to
// ALL reducers
return bindActionCreators({ fetchData: fetchData }, dispatch);
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(TravelList);
我的主要问题问题不是让它按预期进行获取,而是这样做了,但是从来没有调用错误actionCreator,即使我可以在.catch()中console.log“捕获错误”( ),它将记录。但是在reducer中没有更新。
要对此进行检查,我将console.log记录action.type,无论如何,即使记录了“错误捕获”日志,其动作类型也将是FETCH_DATA_SUCCESS。
拔出头发,所以任何建议都很好。
谢谢。
答案 0 :(得分:0)
我认为您提供的代码中没有您的错误。如果您成功登录了调度fetchFailure
的catch中的控制台,则说明您的提取逻辑正在工作。下一步的调试步骤可能是console.log(error)
以确保您收到了您认为已收到的内容,以及console.log(fetchFailure(error))
以确保您正在分派的操作是您认为正在分派的内容。>
如果fetchFailure(error)
返回错误操作,则减速器没有理由收到成功操作:至少在您提供的代码中没有。
答案 1 :(得分:0)
好吧,我是一个傻瓜:)我刚刚检查了我拥有的actionTypes,我意识到我已经两次成功提取数据成功了,无论失败还是成功。感谢您抽出宝贵时间提出建议。标记为已回答
答案 2 :(得分:-1)
由于引发错误,因此需要在化简器中引用error message,而不是错误对象(当前传递给catch
处理程序的错误对象)。
case FETCH_DATA_FAILURE:
console.log('failure should be hit');
// The request failed, but it did stop, so set loading to "false".
// Save the error, and we can display it somewhere
// Since it failed, we don't have items to display anymore, so set it empty.
return {
...state,
loading: false,
error: action.payload.message,
items: []