react-ketting
Version:
Ketting bindings for React
118 lines • 4.14 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.useReadResource = void 0;
const ketting_1 = require("ketting");
const react_1 = require("react");
const use_client_1 = require("./use-client");
const use_resolve_resource_1 = require("./use-resolve-resource");
/**
* The useReadResource hook is an internal hook that helps setting up a lot of
* the plumbing for dealing with resources and state.
*
* It's not recommended for external users to use this directly, instead use
* one of the more specialized hooks such as useResource or useCollection.
*
* Example call:
*
* <pre>
* const {
* loading,
* error,
* resourceState,
* } = useResource(resource);
* </pre>
*
* Returned properties:
*
* * loading - will be true as long as the result is still being fetched from
* the server.
* * error - Will be null or an error object.
* * resourceState - A state object. The `.data` property of this object will
* contain the parsed JSON from the server.
*/
function useReadResource(resourceLike, options) {
const { resource, setResource } = (0, use_resolve_resource_1.useResolveResource)(resourceLike);
const initialState = options.initialState;
const refreshOnStale = options.refreshOnStale || false;
const client = (0, use_client_1.useClient)();
const [resourceState, setResourceState] = useResourceState(resource, initialState, client);
const [loading, setLoading] = (0, react_1.useState)(resourceState === undefined);
const [error, setError] = (0, react_1.useState)(null);
(0, react_1.useEffect)(() => {
// This effect is for setting up the onUpdate event
if (resource === null) {
return;
}
const onUpdate = (newState) => {
setResourceState(newState.clone());
setLoading(false);
};
const onStale = () => {
if (refreshOnStale) {
resource
.refresh()
.catch(err => {
setError(err);
setLoading(false);
});
}
};
resource.on('update', onUpdate);
resource.on('stale', onStale);
return function unmount() {
resource.off('update', onUpdate);
resource.off('stale', onStale);
};
}, [resource]);
(0, react_1.useEffect)(() => {
// This effect is for fetching the initial ResourceState
if (resource === null) {
// No need to fetch resourceState for these cases.
return;
}
if (resourceState && resourceState.uri === resource.uri) {
// Don't do anything if we already have a resourceState, and the
// resourceState's uri matches what we got.
return;
}
// The 'resource' property has changed, so lets get the new resourceState and data.
const cachedState = resource.client.cache.get(resource.uri);
if (cachedState) {
setResourceState(cachedState);
setLoading(false);
return;
}
setResourceState(undefined);
setLoading(true);
resource.get({ headers: options.initialGetRequestHeaders })
.catch(err => {
setError(err);
setLoading(false);
});
}, [resource]);
const result = {
loading,
error,
resourceState: resourceState,
resource: resource,
setResource,
};
return result;
}
exports.useReadResource = useReadResource;
/**
* Internal helper hook to deal with setting up the resource state, and
* populate the cache.
*/
function useResourceState(resource, initialData, client) {
let data = undefined;
if (initialData) {
data = initialData;
}
else if (resource instanceof ketting_1.Resource) {
data = client.cache.get(resource.uri) || undefined;
}
const [resourceState, setResourceState] = (0, react_1.useState)(data);
return [resourceState, setResourceState];
}
//# sourceMappingURL=use-read-resource.js.map
;