@exabytellc/utils
Version:
EB react utils to make everything a little easier!
114 lines (106 loc) • 5.13 kB
JavaScript
import { useCallback, useState } from "react";
import HttpRequest from "../HttpRequest";
/**
* Custom React hook to handle HTTP requests with managed states, errors, progress for upload/download,
* and request lifecycle states (e.g., 'unsent', 'opened', 'uploading', etc.).
* Provides a configurable interface for making HTTP requests and monitoring their state.
*
* @returns {Array} - An array containing:
* - {Function} `call`: Function to trigger the HTTP request with specified options.
* - {boolean} `loading`: Indicator if the request is in progress.
* - {Object} - An object containing:
* - {string|null} `state`: Current request state identifier (e.g., 'unsent', 'opened').
* - {string|null} `stateText`: Descriptive text of the current request state.
* - {any} `response`: Response data from the HTTP request, if successful.
* - {Error|null} `error`: Error object if the request fails, or `null` if no error occurred.
* - {Object|null} `upload`: Upload progress information, typically including bytes sent and total size.
* - {Object|null} `download`: Download progress information, typically including bytes received and total size.
*/
export default function useHttpRequest() {
const [response, setResponse] = useState(null); // Holds the response data after a successful HTTP request.
const [state, setState] = useState(null); // Tracks the current state of the request (e.g., 'unsent', 'opened').
const [stateText, setStateText] = useState(null); // Provides descriptive text for the current state.
const [loading, setLoading] = useState(false); // Boolean flag indicating if the HTTP request is in progress.
const [error, setError] = useState(null); // Stores any error that occurs during the HTTP request.
const [upload, setUpload] = useState(null); // Tracks upload progress, if applicable.
const [download, setDownload] = useState(null); // Tracks download progress, if applicable.
/**
* Initiates an HTTP request with configurable parameters and manages request state (response, error, loading).
*
* @async
* @function call
* @param {Object} options - Configuration options for the HTTP request.
* @param {string} [options.method=null] - HTTP method to use for the request (e.g., 'GET', 'POST', 'PUT', 'DELETE').
* @param {string} [options.address=null] - Full URL or endpoint address to send the request.
* @param {Object} [options.headers=null] - Custom headers to include with the request (e.g., `{ "Content-Type": "application/json" }`).
* @param {Object} [options.urlData=null] - Query parameters to append to the URL (e.g., `{ userId: 123 }`).
* @param {Object|string} [options.bodyData=null] - Request body data, typically an object or string, for methods like POST or PUT.
* @param {string} [options.responseType=null] - Expected response type, such as 'json', 'text', or 'blob'.
* @param {boolean} [options.emptyResponse=false] - If `true`, clears the existing response before making the request.
* @returns {Promise<void>} - Does not return a value but updates the state based on request success or failure.
*
* @example
* call({
* method: 'POST',
* address: 'https://api.example.com/data',
* headers: { 'Authorization': 'Bearer token' },
* bodyData: JSON.stringify({ name: 'Example' }),
* responseType: 'json'
* });
*/
const call = useCallback(async ({
method = null,
address = null,
headers = null,
urlData = null,
bodyData = null,
responseType = null,
emptyResponse = false
}) => {
setLoading(true);
if (emptyResponse) setResponse(null); // Clear response if emptyResponse is true
setError(null);
setUpload(null);
setDownload(null);
const request = new HttpRequest({
method,
address,
headers,
urlData,
bodyData,
responseType,
onStateChange: ({
// requestStates,
currentState,
currentStateText,
// error,
// response,
// currentStats,
currentUpload,
currentDownload
}) => {
setState(currentState); // Update current request state
setStateText(currentStateText); // Update current request state text
// Update upload progress
if (currentStateText == 'uploading') {
setUpload({ ...currentUpload });
}
// Update download progress
if (currentStateText == 'downloading') {
setDownload({ ...currentDownload });
}
}
});
try {
await request.send();
const res = request?.response;
setResponse(res); // Update response state on successful request
} catch (e) {
console.error(e);
setError(request.error); // Set error state if the request fails
} finally {
setLoading(false); // Set loading to false once request completes
}
}, []);
return [call, loading, { state, stateText, response, error, upload, download }];
}