[英]React Hooks - proper way of handling errors
在反应钩子中处理错误等的最佳方法是什么? 假设我有一些像useAjax
这样的自定义 Ajax Hook,它返回数据、错误和可以触发请求的函数。 现在我有两种处理错误的方法。 在某些函数中或通过useEffect
。 下面的例子:
const {data, error, sendRequest} = useAjax()
const handleSubmit = () => {
sendRequest()
}
useEffect(() => {
if (error) {
// display some error/set state
}
}, [error])
或者
const {data, error, sendRequest} = useAjax()
const handleSubmit = async () => {
try {
await sendRequest()
} catch {
//display error
// set some state
}
}
哪种方法是正确的? 第二个似乎更有效,但它与钩子有点争论,因为我们可能不使用由钩子错误或数据返回的。
基本上你可以用不同的方式处理错误。 其中之一也可以来自 axios Interceptor,这可以是您对任何类型的 API 调用的全局错误处理。 除了基于本地组件的错误处理,您还可以添加全局错误处理。 为此,您可以以以下为例:
// Axios 实例
const api = axios.create({
baseURL,
});
// 使用 axios 请求拦截器设置访问令牌
api.interceptors.request.use(
(config) => {
showAppLoader();
// Token from localStorage
const token = store.get('access_token');
if (token) {
config.headers['Authorization'] = 'Bearer ' + token;
}
return config;
},
(error) => {
hideAppLoader();
Promise.reject(error);
}
);
// 使用 axios 响应拦截器处理刷新令牌
api.interceptors.response.use(
(response) => {
hideAppLoader();
return response;
},
(error) => {
hideAppLoader();
const originalRequest = error.config;
// Prevent infinite loop when refresh token request is 401;
if (
error.response.status === 401 &&
originalRequest.url === `${baseURL}${endpoints.TOKEN}`
) {
return Promise.reject(error);
}
if (error.response.status === 401 && !originalRequest._retry) {
originalRequest._retry = true;
// Refresh token from localStorage
const refreshToken = store.get('refresh_token');
// Refresh token request body
const data = new FormData();
data.append('type', 'refresh_token');
data.append('refresh_token', refreshToken);
return axios
.post(endpoints.TOKEN, data, {
auth: {
// eslint-disable-next-line no-undef
username: process.env['REACT_APP_CLIENT_ID'],
// eslint-disable-next-line no-undef
password: process.env['REACT_APP_CLIENT_SECRET'],
},
})
.then((res) => {
if (res.status === 200 && res.data) {
const new_access_token = res.data.access_token;
const new_refresh_token = res.data.refresh_token;
// Set new tokens to localStorage
store.set('access_token', new_access_token);
store.set('refresh_token', new_refresh_token);
api.defaults.headers.common['Authorization'] =
'Bearer ' + new_access_token;
return api(originalRequest);
}
})
.catch((err) => {
// Reset tokens to localStorage if refresh token failed
store.set('access_token', '');
store.set('refresh_token', '');
});
}
// disableBadReqGlobalError = Disable Error Notification for bad request/400 error!
const { disableBadReqGlobalError } = originalRequest;
if (error.response.status === 500) {
showServerErrorAlert();
}
if (error.response.status === 400 && !disableBadReqGlobalError) {
notification(
'400 - Bad Request',
'Wrong information provided on the form! Please correct and try again!',
'warning'
);
}
if (error.response.status === 404) {
notification(
'404 - Not Found',
'Something went wrong! Sorry for this inconvenience. Please contact with us.',
'error'
);
}
return Promise.reject(error);
}
);
您可以根据需要添加更多错误状态。 这将帮助您捕获所有类型的全局错误。 如果您不想显示全局错误,而不想显示本地化错误,那么您还可以将disableBadReqGlobalError作为参数传递以忽略此错误处理。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.