UNPKG

react-relay

Version:

A framework for building GraphQL-driven React applications.

130 lines (129 loc) 6.96 kB
'use strict'; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault")["default"]; var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2")); var getConnectionState = require('./getConnectionState'); var useIsMountedRef = require('./useIsMountedRef'); var useIsOperationNodeActive = require('./useIsOperationNodeActive'); var useRelayEnvironment = require('./useRelayEnvironment'); var invariant = require('invariant'); var _require = require('react'), useCallback = _require.useCallback, useRef = _require.useRef, useState = _require.useState; var _require2 = require('relay-runtime'), fetchQuery = _require2.__internal.fetchQuery, createOperationDescriptor = _require2.createOperationDescriptor, getPaginationVariables = _require2.getPaginationVariables, getRefetchMetadata = _require2.getRefetchMetadata, getSelector = _require2.getSelector; var warning = require("fbjs/lib/warning"); function useLoadMoreFunction_EXPERIMENTAL(args) { var direction = args.direction, fragmentNode = args.fragmentNode, fragmentRef = args.fragmentRef, fragmentIdentifier = args.fragmentIdentifier, fragmentData = args.fragmentData, connectionPathInFragmentData = args.connectionPathInFragmentData, paginationRequest = args.paginationRequest, paginationMetadata = args.paginationMetadata, componentDisplayName = args.componentDisplayName, observer = args.observer, onReset = args.onReset; var environment = useRelayEnvironment(); var _getRefetchMetadata = getRefetchMetadata(fragmentNode, componentDisplayName), identifierInfo = _getRefetchMetadata.identifierInfo; var identifierValue = (identifierInfo === null || identifierInfo === void 0 ? void 0 : identifierInfo.identifierField) != null && fragmentData != null && typeof fragmentData === 'object' ? fragmentData[identifierInfo.identifierField] : null; var fetchStatusRef = useRef({ kind: 'none' }); var _useState = useState(environment), mirroredEnvironment = _useState[0], setMirroredEnvironment = _useState[1]; var _useState2 = useState(fragmentIdentifier), mirroredFragmentIdentifier = _useState2[0], setMirroredFragmentIdentifier = _useState2[1]; var isParentQueryActive = useIsOperationNodeActive(fragmentNode, fragmentRef); var forceDisposeFn = useCallback(function () { if (fetchStatusRef.current.kind === 'fetching') { fetchStatusRef.current.subscription.unsubscribe(); } fetchStatusRef.current = { kind: 'none' }; }, []); var shouldReset = environment !== mirroredEnvironment || fragmentIdentifier !== mirroredFragmentIdentifier; if (shouldReset) { forceDisposeFn(); onReset(); setMirroredEnvironment(environment); setMirroredFragmentIdentifier(fragmentIdentifier); } var _getConnectionState = getConnectionState(direction, fragmentNode, fragmentData, connectionPathInFragmentData), cursor = _getConnectionState.cursor, hasMore = _getConnectionState.hasMore; var isMountedRef = useIsMountedRef(); var loadMore = useCallback(function (count, options) { var onComplete = options === null || options === void 0 ? void 0 : options.onComplete; if (isMountedRef.current !== true) { process.env.NODE_ENV !== "production" ? warning(false, 'Relay: Unexpected fetch on unmounted component for fragment ' + '`%s` in `%s`. It looks like some instances of your component are ' + 'still trying to fetch data but they already unmounted. ' + 'Please make sure you clear all timers, intervals, ' + 'async calls, etc that may trigger a fetch.', fragmentNode.name, componentDisplayName) : void 0; return { dispose: function dispose() {} }; } var fragmentSelector = getSelector(fragmentNode, fragmentRef); if (fetchStatusRef.current.kind === 'fetching' || fragmentData == null || isParentQueryActive) { if (fragmentSelector == null) { process.env.NODE_ENV !== "production" ? warning(false, 'Relay: Unexpected fetch while using a null fragment ref ' + 'for fragment `%s` in `%s`. When fetching more items, we expect ' + "initial fragment data to be non-null. Please make sure you're " + 'passing a valid fragment ref to `%s` before paginating.', fragmentNode.name, componentDisplayName, componentDisplayName) : void 0; } if (onComplete) { onComplete(null); } return { dispose: function dispose() {} }; } !(fragmentSelector != null && fragmentSelector.kind !== 'PluralReaderSelector') ? process.env.NODE_ENV !== "production" ? invariant(false, 'Relay: Expected to be able to find a non-plural fragment owner for ' + "fragment `%s` when using `%s`. If you're seeing this, " + 'this is likely a bug in Relay.', fragmentNode.name, componentDisplayName) : invariant(false) : void 0; var parentVariables = fragmentSelector.owner.variables; var fragmentVariables = fragmentSelector.variables; var extraVariables = options === null || options === void 0 ? void 0 : options.UNSTABLE_extraVariables; var baseVariables = (0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, parentVariables), fragmentVariables); var paginationVariables = getPaginationVariables(direction, count, cursor, baseVariables, (0, _objectSpread2["default"])({}, extraVariables), paginationMetadata); if (identifierInfo != null) { if (typeof identifierValue !== 'string') { process.env.NODE_ENV !== "production" ? warning(false, 'Relay: Expected result to have a string ' + '`%s` in order to refetch, got `%s`.', identifierInfo.identifierField, identifierValue) : void 0; } paginationVariables[identifierInfo.identifierQueryVariableName] = identifierValue; } var paginationQuery = createOperationDescriptor(paginationRequest, paginationVariables, { force: true }); fetchQuery(environment, paginationQuery).subscribe((0, _objectSpread2["default"])((0, _objectSpread2["default"])({}, observer), {}, { start: function start(subscription) { fetchStatusRef.current = { kind: 'fetching', subscription: subscription }; observer.start && observer.start(subscription); }, complete: function complete() { fetchStatusRef.current = { kind: 'none' }; observer.complete && observer.complete(); onComplete && onComplete(null); }, error: function error(_error) { fetchStatusRef.current = { kind: 'none' }; observer.complete && observer.complete(); onComplete && onComplete(_error); } })); return { dispose: function dispose() {} }; }, [environment, identifierValue, direction, cursor, isParentQueryActive, fragmentData, fragmentNode.name, fragmentRef, componentDisplayName]); return [loadMore, hasMore, forceDisposeFn]; } module.exports = useLoadMoreFunction_EXPERIMENTAL;