使用 Axios 和 Redux 添加错误状态
Adding an error state with Axios and Redux
我在让我的应用程序按我希望的方式运行时遇到了一些麻烦。我对 React 和 Redux 还很陌生,所以请多多包涵。
现在我可以调用 this.props.fetchData('usernamehere')
来获取有关用户的一些数据,当它成功时它会更新 this.props.profile
,我用它来更新 React 组件。问题在于处理错误。
我试图通过添加一个 FETCH_DATA_ERROR
reducer 来解决这个问题,但我遇到的问题是当它出现 404 时它仍然用一个空对象替换 this.props.profile
而不是仅仅更新this.props.error
。理想情况下,我想保留当前的配置文件,直到它成功找到新的配置文件,然后通过更新 this.props.error
向用户显示他们输入的用户名有什么错误。
现在我有以下动作创建器设置:
import axios from 'axios';
import { FETCH_DATA, FETCH_DATA_ERROR } from './types';
export const ROOT_URL = 'https://api.github.com/users'
export function fetchData(user) {
const request = axios.get(`${ROOT_URL}/${user}`)
.catch(function (error) {
return {
type: FETCH_DATA_ERROR,
payload: error
}
});
return {
type: FETCH_DATA,
payload: request
}
}
和减速器:
import { FETCH_DATA, FETCH_DATA_ERROR } from '../actions/types';
const INITIAL_STATE = { profile: null, error: null }
export default function(state = INITIAL_STATE, action) {
switch(action.type) {
case FETCH_DATA:
return { ...state, profile: action.payload.data };
case FETCH_DATA_ERROR:
return { ...state, error: action.payload };
default:
return state;
}
}
如果有人有任何建议,我们将不胜感激。我觉得我在正确的道路上,但似乎无法弄清楚我哪里错了。
到目前为止,您有一个表示请求开始的操作 (FETCH_DATA
) 和一个表示请求失败的操作 (FETCH_DATA_ERROR
)。通常这是用第三个模型建模的,表示请求产生了积极响应(可能 FETCH_DATA_SUCCESS
)。
您需要使用 https://github.com/gaearon/redux-thunk 之类的东西重写您的 action creator,以便它首先仅发送 FETCH_DATA
,然后在 axios.get
的 then/catch-handlers 中发送成功或失败的操作:
import { FETCH_DATA, FETCH_DATA_SUCCESS, FETCH_DATA_ERROR } from '../actions/types';
// ASYNC ACTION CREATOR
export const fetchData = user => (dispatch) => {
dispatch({
type: FETCH_DATA
});
return axios.get(`${ROOT_URL}/${user}`)
.then(response => dispatch({
type: FETCH_DATA_SUCCESS,
payload: response
}))
.catch(error => dispatch({
type: FETCH_DATA_ERROR,
payload: error
}));
};
// REDUCER
const INITIAL_STATE = {
profile: null,
error: null
};
export default function(state = INITIAL_STATE, action) {
switch(action.type) {
// Start of request - discard old data and reset old errors.
case FETCH_DATA:
return {
// It's important to set all of these to properly model the request lifecycle
// and avoid race conditions etc.
profile: null,
error: null
};
// End of request - save profile and signal that there was no error.
case FETCH_DATA_SUCCESS:
return {
profile: action.payload.data,
error: null
};
// End of request - discard old profile and save error, to display it to the user for example.
case FETCH_DATA_ERROR:
return {
profile: null,
error: action.payload
};
default:
return state;
}
}
我在让我的应用程序按我希望的方式运行时遇到了一些麻烦。我对 React 和 Redux 还很陌生,所以请多多包涵。
现在我可以调用 this.props.fetchData('usernamehere')
来获取有关用户的一些数据,当它成功时它会更新 this.props.profile
,我用它来更新 React 组件。问题在于处理错误。
我试图通过添加一个 FETCH_DATA_ERROR
reducer 来解决这个问题,但我遇到的问题是当它出现 404 时它仍然用一个空对象替换 this.props.profile
而不是仅仅更新this.props.error
。理想情况下,我想保留当前的配置文件,直到它成功找到新的配置文件,然后通过更新 this.props.error
向用户显示他们输入的用户名有什么错误。
现在我有以下动作创建器设置:
import axios from 'axios';
import { FETCH_DATA, FETCH_DATA_ERROR } from './types';
export const ROOT_URL = 'https://api.github.com/users'
export function fetchData(user) {
const request = axios.get(`${ROOT_URL}/${user}`)
.catch(function (error) {
return {
type: FETCH_DATA_ERROR,
payload: error
}
});
return {
type: FETCH_DATA,
payload: request
}
}
和减速器:
import { FETCH_DATA, FETCH_DATA_ERROR } from '../actions/types';
const INITIAL_STATE = { profile: null, error: null }
export default function(state = INITIAL_STATE, action) {
switch(action.type) {
case FETCH_DATA:
return { ...state, profile: action.payload.data };
case FETCH_DATA_ERROR:
return { ...state, error: action.payload };
default:
return state;
}
}
如果有人有任何建议,我们将不胜感激。我觉得我在正确的道路上,但似乎无法弄清楚我哪里错了。
到目前为止,您有一个表示请求开始的操作 (FETCH_DATA
) 和一个表示请求失败的操作 (FETCH_DATA_ERROR
)。通常这是用第三个模型建模的,表示请求产生了积极响应(可能 FETCH_DATA_SUCCESS
)。
您需要使用 https://github.com/gaearon/redux-thunk 之类的东西重写您的 action creator,以便它首先仅发送 FETCH_DATA
,然后在 axios.get
的 then/catch-handlers 中发送成功或失败的操作:
import { FETCH_DATA, FETCH_DATA_SUCCESS, FETCH_DATA_ERROR } from '../actions/types';
// ASYNC ACTION CREATOR
export const fetchData = user => (dispatch) => {
dispatch({
type: FETCH_DATA
});
return axios.get(`${ROOT_URL}/${user}`)
.then(response => dispatch({
type: FETCH_DATA_SUCCESS,
payload: response
}))
.catch(error => dispatch({
type: FETCH_DATA_ERROR,
payload: error
}));
};
// REDUCER
const INITIAL_STATE = {
profile: null,
error: null
};
export default function(state = INITIAL_STATE, action) {
switch(action.type) {
// Start of request - discard old data and reset old errors.
case FETCH_DATA:
return {
// It's important to set all of these to properly model the request lifecycle
// and avoid race conditions etc.
profile: null,
error: null
};
// End of request - save profile and signal that there was no error.
case FETCH_DATA_SUCCESS:
return {
profile: action.payload.data,
error: null
};
// End of request - discard old profile and save error, to display it to the user for example.
case FETCH_DATA_ERROR:
return {
profile: null,
error: action.payload
};
default:
return state;
}
}