add useEndpoint hook

This commit is contained in:
Keith Grant 2020-01-27 10:20:47 -08:00
parent 55e720e25d
commit d15f7b76fa
2 changed files with 52 additions and 30 deletions

View File

@ -1,4 +1,4 @@
import React, { useState, useEffect, useRef } from 'react';
import React, { useCallback } from 'react';
import { Link, useHistory } from 'react-router-dom';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
@ -11,37 +11,19 @@ import DeleteButton from '@components/DeleteButton';
import ContentError from '@components/ContentError';
import ContentLoading from '@components/ContentLoading';
import { InventoriesAPI } from '@api';
import useEndpoint from './useEndpoint';
import { Inventory } from '../../../types';
function InventoryDetail({ inventory, i18n }) {
const [instanceGroups, setInstanceGroups] = useState([]);
const [hasContentLoading, setHasContentLoading] = useState(true);
const [contentError, setContentError] = useState(null);
const history = useHistory();
const isMounted = useRef(null);
useEffect(() => {
isMounted.current = true;
(async () => {
setHasContentLoading(true);
try {
const { data } = await InventoriesAPI.readInstanceGroups(inventory.id);
if (!isMounted.current) {
return;
}
setInstanceGroups(data.results);
} catch (err) {
setContentError(err);
} finally {
if (isMounted.current) {
setHasContentLoading(false);
}
}
})();
return () => {
isMounted.current = false;
};
}, [inventory.id]);
const { results: instanceGroups, isLoading, error } = useEndpoint(
useCallback(async () => {
const { data } = await InventoriesAPI.readInstanceGroups(inventory.id);
return data.results;
}, [inventory.id]),
inventory.id
);
const deleteInventory = async () => {
await InventoriesAPI.destroy(inventory.id);
@ -53,12 +35,12 @@ function InventoryDetail({ inventory, i18n }) {
user_capabilities: userCapabilities,
} = inventory.summary_fields;
if (hasContentLoading) {
if (isLoading) {
return <ContentLoading />;
}
if (contentError) {
return <ContentError error={contentError} />;
if (error) {
return <ContentError error={error} />;
}
return (

View File

@ -0,0 +1,40 @@
import { useEffect, useState, useRef } from 'react';
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,
};
}