@replyke/core
Version:
Replyke: Build interactive apps with social features like comments, votes, feeds, user lists, notifications, and more.
114 lines • 4.03 kB
JavaScript
import { useCallback, useEffect, useRef, useState } from "react";
import useFetchEntity from "./useFetchEntity";
import useFetchEntityByForeignId from "./useFetchEntityByForeignId";
import useFetchEntityByShortId from "./useFetchEntityByShortId";
import useUpdateEntity from "./useUpdateEntity";
import useDeleteEntity from "./useDeleteEntity";
import { handleError } from "../../utils/handleError";
function useEntityData({ entityId, foreignId, shortId, entity: entityProp, createIfNotFound, }) {
const [entity, setEntity] = useState(entityProp);
// Cache to store fetched entities keyed by unique identifier
const entityCache = useRef({});
const fetchEntity = useFetchEntity();
const fetchEntityByForeignId = useFetchEntityByForeignId();
const fetchEntityByShortId = useFetchEntityByShortId();
const updateEntity = useUpdateEntity();
const deleteEntity = useDeleteEntity();
const handleUpdateEntity = useCallback(async ({ update }) => {
if (!entity)
return;
try {
const newEntity = await updateEntity({
entityId: entity.id,
update,
});
if (newEntity)
setEntity(newEntity);
return newEntity;
}
catch (err) {
handleError(err, "Failed to update entity");
}
}, [entity, updateEntity]);
const handleDeleteEntity = useCallback(async () => {
if (!entity)
return;
try {
await deleteEntity({ entityId: entity.id });
setEntity(undefined);
}
catch (err) {
handleError(err, "Failed to delete entity");
}
}, [entity, deleteEntity]);
useEffect(() => {
const handleFetchEntity = async () => {
if (!foreignId && !entityId && !shortId)
return;
if (entity && entityId && entity.id === entityId)
return;
if (entity && foreignId && entity.foreignId === foreignId)
return;
if (entity && shortId && entity.shortId === shortId)
return;
const uniqueKey = `${entityId ?? ""}-${foreignId ?? ""}-${shortId ?? ""}`;
// If we have a cached entity, update the state and exit.
if (entityCache.current[uniqueKey]) {
setEntity(entityCache.current[uniqueKey]);
return;
}
try {
let fetchedEntity = null;
if (entityId) {
fetchedEntity = await fetchEntity({
entityId,
});
}
else if (foreignId) {
fetchedEntity = await fetchEntityByForeignId({
foreignId,
createIfNotFound,
});
}
else if (shortId) {
fetchedEntity = await fetchEntityByShortId({
shortId,
});
}
if (fetchedEntity) {
// Store the fetched entity in cache.
entityCache.current[uniqueKey] = fetchedEntity;
setEntity(fetchedEntity);
}
else {
setEntity(null);
}
}
catch (err) {
handleError(err, "Failed to fetch entity");
}
};
handleFetchEntity();
}, [
fetchEntity,
fetchEntityByForeignId,
fetchEntityByShortId,
entityId,
foreignId,
shortId,
entity,
createIfNotFound,
]);
useEffect(() => {
if (entityProp)
setEntity(entityProp);
}, [entityProp]);
return {
entity,
setEntity,
updateEntity: handleUpdateEntity,
deleteEntity: handleDeleteEntity,
};
}
export default useEntityData;
//# sourceMappingURL=useEntityData.js.map