react如何封装fetch
封装 Fetch 的基本方法
在 React 中封装 Fetch 可以提高代码复用性和可维护性。以下是一个简单的封装示例,包含错误处理和请求配置:
const fetchData = async (url, options = {}) => {
const defaultHeaders = {
'Content-Type': 'application/json',
};
try {
const response = await fetch(url, {
...options,
headers: {
...defaultHeaders,
...options.headers,
},
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
} catch (error) {
console.error('Fetch error:', error);
throw error;
}
};
添加请求拦截功能
扩展封装以支持请求和响应拦截器,提供更灵活的控制:

const createFetch = () => {
const interceptors = {
request: [],
response: [],
};
const addInterceptor = (type, interceptor) => {
interceptors[type].push(interceptor);
};
const runInterceptors = async (type, initialValue) => {
return interceptors[type].reduce(
async (chain, interceptor) => interceptor(await chain),
Promise.resolve(initialValue)
);
};
const fetchWithInterceptors = async (url, options = {}) => {
try {
const modifiedOptions = await runInterceptors('request', options);
const response = await fetch(url, modifiedOptions);
const processedResponse = await runInterceptors('response', response);
return processedResponse.json();
} catch (error) {
console.error('Fetch with interceptors error:', error);
throw error;
}
};
return {
fetch: fetchWithInterceptors,
addRequestInterceptor: (interceptor) => addInterceptor('request', interceptor),
addResponseInterceptor: (interceptor) => addInterceptor('response', interceptor),
};
};
使用自定义 Hook 封装
创建 React Hook 风格的封装,便于在组件中使用:

import { useState, useEffect } from 'react';
const useFetch = (url, options) => {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch(url, options);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const result = await response.json();
setData(result);
} catch (err) {
setError(err);
} finally {
setLoading(false);
}
};
fetchData();
}, [url, options]);
return { data, loading, error };
};
支持缓存和防抖
添加缓存机制和防抖功能优化性能:
const createAdvancedFetch = () => {
const cache = new Map();
let debounceTimer;
const fetchWithCache = async (url, options = {}, useCache = true) => {
if (useCache && cache.has(url)) {
return cache.get(url);
}
clearTimeout(debounceTimer);
return new Promise((resolve) => {
debounceTimer = setTimeout(async () => {
try {
const response = await fetch(url, options);
const data = await response.json();
if (useCache) {
cache.set(url, data);
}
resolve(data);
} catch (error) {
console.error('Advanced fetch error:', error);
throw error;
}
}, 300);
});
};
return { fetch: fetchWithCache };
};
处理文件上传
扩展封装以支持文件上传功能:
const uploadFile = async (url, file, additionalData = {}) => {
const formData = new FormData();
formData.append('file', file);
Object.entries(additionalData).forEach(([key, value]) => {
formData.append(key, value);
});
try {
const response = await fetch(url, {
method: 'POST',
body: formData,
});
if (!response.ok) {
throw new Error(`Upload failed with status ${response.status}`);
}
return await response.json();
} catch (error) {
console.error('File upload error:', error);
throw error;
}
};
以上封装方法可以根据项目需求组合使用或进一步扩展。每种方法都针对不同场景进行了优化,开发者可以根据实际需求选择合适的封装方式。






