rename useFetch to useRequest

This commit is contained in:
Keith Grant 2020-01-30 16:13:19 -08:00
parent aaf371ee23
commit ef2fa26126
5 changed files with 48 additions and 127 deletions

View File

@ -24,6 +24,7 @@ import UnifiedJobs from './models/UnifiedJobs';
import Users from './models/Users';
import WorkflowJobs from './models/WorkflowJobs';
import WorkflowJobTemplates from './models/WorkflowJobTemplates';
import useRequest from './useRequest';
const AdHocCommandsAPI = new AdHocCommands();
const ConfigAPI = new Config();
@ -79,4 +80,5 @@ export {
UsersAPI,
WorkflowJobsAPI,
WorkflowJobTemplatesAPI,
useRequest,
};

View File

@ -0,0 +1,38 @@
import { useEffect, useState, useRef, useCallback } from 'react';
export default function useRequest(makeRequest, initialValue) {
const [result, setResult] = useState(initialValue);
const [error, setError] = useState(null);
const [isLoading, setIsLoading] = useState(false);
const isMounted = useRef(null);
useEffect(() => {
isMounted.current = true;
return () => {
isMounted.current = false;
};
}, []);
return {
result,
error,
isLoading,
request: useCallback(async () => {
setIsLoading(true);
try {
const response = await makeRequest();
if (isMounted.current) {
setResult(response);
}
} catch (err) {
if (isMounted.current) {
setError(err);
}
} finally {
if (isMounted.current) {
setIsLoading(false);
}
}
}, [makeRequest]),
};
}

View File

@ -10,28 +10,18 @@ import { VariablesDetail } from '@components/CodeMirrorInput';
import DeleteButton from '@components/DeleteButton';
import ContentError from '@components/ContentError';
import ContentLoading from '@components/ContentLoading';
import { InventoriesAPI } from '@api';
import useEndpoint, { useFetch } from './useEndpoint';
import { InventoriesAPI, useRequest } from '@api';
import { Inventory } from '../../../types';
function InventoryDetail({ inventory, i18n }) {
const history = useHistory();
// initial approach with useEndpoint()
// const { results: instanceGroups, isLoading, error } = useEndpoint(
// useCallback(async () => {
// const { data } = await InventoriesAPI.readInstanceGroups(inventory.id);
// return data.results;
// }, [inventory.id])
// );
// more versatile approach with useFetch()
const {
result: instanceGroups,
isLoading,
error,
fetch: fetchInstanceGroups,
} = useFetch(
request: fetchInstanceGroups,
} = useRequest(
useCallback(async () => {
const { data } = await InventoriesAPI.readInstanceGroups(inventory.id);
return data.results;

View File

@ -1,79 +0,0 @@
import { useEffect, useState, useRef, useCallback } from 'react';
// Initial approach (useEffect baked in)
export default function useEndpoint(fetch) {
const [results, setResults] = useState([]);
const [error, setError] = useState(null);
const [isLoading, setIsLoading] = useState(true);
const isMounted = useRef(null);
useEffect(() => {
isMounted.current = true;
(async () => {
// Do we want this set here or not? Can result in extra
// unmounting/re-mounting of child components
setIsLoading(true);
try {
const fetchedResults = await fetch();
if (isMounted.current) {
setResults(fetchedResults);
}
} catch (err) {
if (isMounted.current) {
setError(err);
}
} finally {
if (isMounted.current) {
setIsLoading(false);
}
}
})();
return () => {
isMounted.current = false;
};
}, [fetch]);
return {
results,
isLoading,
error,
};
}
// more versatile approach (returns function to make API request)
export function useFetch(fetch, initialValue) {
const [result, setResult] = useState(initialValue);
const [error, setError] = useState(null);
const [isLoading, setIsLoading] = useState(false);
const isMounted = useRef(null);
useEffect(() => {
isMounted.current = true;
return () => {
isMounted.current = false;
};
}, []);
return {
result,
error,
isLoading,
fetch: useCallback(async () => {
setIsLoading(true);
try {
const response = await fetch();
if (isMounted.current) {
setResult(response);
}
} catch (err) {
if (isMounted.current) {
setError(err);
}
} finally {
if (isMounted.current) {
setIsLoading(false);
}
}
}, [fetch]),
};
}

View File

@ -4,7 +4,7 @@ import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { Card, PageSection } from '@patternfly/react-core';
import { OrganizationsAPI } from '@api';
import { OrganizationsAPI, useRequest } from '@api';
import AlertModal from '@components/AlertModal';
import DataListToolbar from '@components/DataListToolbar';
import ErrorDetail from '@components/ErrorDetail';
@ -13,10 +13,6 @@ import PaginatedDataList, {
ToolbarDeleteButton,
} from '@components/PaginatedDataList';
import { getQSConfig, parseQueryString } from '@util/qs';
// TODO: move useEndpoint to better location
import useEndpoint, {
useFetch,
} from '../../Inventory/InventoryDetail/useEndpoint';
import OrganizationListItem from './OrganizationListItem';
@ -35,38 +31,12 @@ function OrganizationsList({ i18n }) {
const addUrl = `${match.url}/add`;
// const {
// results: organizations,
// error: contentError,
// isLoading: isOrgsLoading,
// } = useEndpoint(
// useCallback(async () => {
// const params = parseQueryString(QS_CONFIG, location.search);
// const [
// {
// data: { count, results },
// },
// {
// data: { actions },
// },
// ] = await Promise.all([
// OrganizationsAPI.read(params),
// loadOrganizationActions(),
// ]);
// return {
// organizations: results,
// count,
// actions,
// };
// }, [location])
// );
const {
result: { organizations = {}, organizationCount, actions },
error: contentError,
isLoading: isOrgsLoading,
fetch: fetchOrganizations,
} = useFetch(
request: fetchOrganizations,
} = useRequest(
useCallback(async () => {
const params = parseQueryString(QS_CONFIG, location.search);
const [orgs, orgActions] = await Promise.all([
@ -89,8 +59,8 @@ function OrganizationsList({ i18n }) {
const {
isLoading: isDeleteLoading,
// error: deletionError,
fetch: deleteOrganizations,
} = useFetch(
request: deleteOrganizations,
} = useRequest(
useCallback(async () => {
return Promise.all(
selected.map(({ id }) => OrganizationsAPI.destroy(id))