Skip to content

Commit

Permalink
Update react-cache hooks types to match legacy hooks types
Browse files Browse the repository at this point in the history
Reviewed By: josephsavona

Differential Revision: D48971708

fbshipit-source-id: fa18cd1321ac468254b9e55fb6677957953a5491
  • Loading branch information
alunyov authored and facebook-github-bot committed Sep 6, 2023
1 parent 440877a commit d9a099e
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 91 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,23 +30,17 @@ declare function useFragment<TFragmentType: FragmentType, TData>(
key: HasSpread<TFragmentType>,
): TData;

// if the key is nullable, return nullable value
declare function useFragment<TFragmentType: FragmentType, TData>(
fragment: Fragment<TFragmentType, TData>,
key: ?HasSpread<TFragmentType>,
): ?TData;

// if the key is a non-nullable array of keys, return non-nullable array
declare function useFragment<TFragmentType: FragmentType, TData>(
fragment: Fragment<TFragmentType, TData>,
key: $ReadOnlyArray<HasSpread<TFragmentType>>,
): TData;

// if the key is a nullable array of keys, return nullable array
// if the key is null/void, return null/void value
declare function useFragment<TFragmentType: FragmentType, TData>(
fragment: Fragment<TFragmentType, TData>,
key: ?$ReadOnlyArray<HasSpread<TFragmentType>>,
): ?TData;
key: null | void,
): null | void;

function useFragment(fragment: GraphQLTaggedNode, key: mixed): mixed {
// We need to use this hook in order to be able to track if
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,15 @@
'use strict';

import type {LoadMoreFn, UseLoadMoreFunctionArgs} from '../useLoadMoreFunction';
import type {ReturnType} from '../usePaginationFragment';
import type {Options} from './useRefetchableFragmentInternal_REACT_CACHE';
import type {RefetchFnDynamic} from './useRefetchableFragmentInternal_REACT_CACHE';
import type {
FragmentType,
GraphQLResponse,
GraphQLTaggedNode,
Observer,
OperationType,
RefetchableFragment,
Variables,
} from 'relay-runtime';
import type {VariablesOf} from 'relay-runtime/util/RelayRuntimeTypes';

const useLoadMoreFunction = require('../useLoadMoreFunction');
const useRelayEnvironment = require('../useRelayEnvironment');
Expand All @@ -35,36 +33,15 @@ const {
getPaginationMetadata,
} = require('relay-runtime');

export type ReturnType<TQuery: OperationType, TKey, TFragmentData> = {
data: TFragmentData,
loadNext: LoadMoreFn<TQuery['variables']>,
loadPrevious: LoadMoreFn<TQuery['variables']>,
hasNext: boolean,
hasPrevious: boolean,
isLoadingNext: boolean,
isLoadingPrevious: boolean,
refetch: RefetchFnDynamic<TQuery, TKey>,
};

function usePaginationFragment<
TQuery: OperationType,
TKey: ?{+$data?: mixed, +$fragmentSpreads: FragmentType, ...},
TFragmentType: FragmentType,
TVariables: Variables,
TData,
TKey: ?{+$fragmentSpreads: TFragmentType, ...},
>(
fragmentInput: GraphQLTaggedNode,
fragmentInput: RefetchableFragment<TFragmentType, TData, TVariables>,
parentFragmentRef: TKey,
): ReturnType<
TQuery,
TKey,
// NOTE: This $Call ensures that the type of the returned data is either:
// - nullable if the provided ref type is nullable
// - non-nullable if the provided ref type is non-nullable
// prettier-ignore
$Call<
& (<TFragmentData>( { +$data?: TFragmentData, ... }) => TFragmentData)
& (<TFragmentData>(?{ +$data?: TFragmentData, ... }) => ?TFragmentData),
TKey,
>,
> {
): ReturnType<TVariables, TData, TKey> {
const fragmentNode = getFragment(fragmentInput);
useStaticFragmentNodeWarning(
fragmentNode,
Expand All @@ -76,14 +53,14 @@ function usePaginationFragment<
getPaginationMetadata(fragmentNode, componentDisplayName);

const {fragmentData, fragmentRef, refetch} = useRefetchableFragmentInternal<
TQuery,
TKey,
{variables: TVariables, response: TData},
{data?: TData},
>(fragmentNode, parentFragmentRef, componentDisplayName);
const fragmentIdentifier = getFragmentIdentifier(fragmentNode, fragmentRef);

// Backward pagination
const [loadPrevious, hasPrevious, isLoadingPrevious, disposeFetchPrevious] =
useLoadMore<TQuery['variables']>({
useLoadMore<TVariables>({
componentDisplayName,
connectionPathInFragmentData,
direction: 'backward',
Expand All @@ -96,22 +73,21 @@ function usePaginationFragment<
});

// Forward pagination
const [loadNext, hasNext, isLoadingNext, disposeFetchNext] = useLoadMore<
TQuery['variables'],
>({
componentDisplayName,
connectionPathInFragmentData,
direction: 'forward',
fragmentData,
fragmentIdentifier,
fragmentNode,
fragmentRef,
paginationMetadata,
paginationRequest,
});
const [loadNext, hasNext, isLoadingNext, disposeFetchNext] =
useLoadMore<TVariables>({
componentDisplayName,
connectionPathInFragmentData,
direction: 'forward',
fragmentData,
fragmentIdentifier,
fragmentNode,
fragmentRef,
paginationMetadata,
paginationRequest,
});

const refetchPagination: RefetchFnDynamic<TQuery, TKey> = useCallback(
(variables: VariablesOf<TQuery>, options: void | Options) => {
const refetchPagination = useCallback(
(variables: TVariables, options: void | Options) => {
disposeFetchNext();
disposeFetchPrevious();
return refetch(variables, {...options, __environment: undefined});
Expand All @@ -131,6 +107,7 @@ function usePaginationFragment<
});
}
return {
// $FlowFixMe[incompatible-return]
data: fragmentData,
loadNext,
loadPrevious,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ type RefetchFnExact<TQuery: OperationType, TOptions = Options> = RefetchFnBase<
type RefetchFnInexact<
TQuery: OperationType,
TOptions = Options,
> = RefetchFnBase<Partial<VariablesOf<TQuery>>, TOptions>;
> = RefetchFnBase<$ReadOnly<Partial<VariablesOf<TQuery>>>, TOptions>;

type Action =
| {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,55 +11,39 @@

'use strict';

import type {RefetchFnDynamic} from './useRefetchableFragmentInternal_REACT_CACHE';
import type {
FragmentType,
GraphQLTaggedNode,
OperationType,
} from 'relay-runtime';
import type {ReturnType} from '../useRefetchableFragment';
import type {FragmentType, RefetchableFragment, Variables} from 'relay-runtime';

const useStaticFragmentNodeWarning = require('../useStaticFragmentNodeWarning');
const useRefetchableFragmentInternal = require('./useRefetchableFragmentInternal_REACT_CACHE');
const {useDebugValue} = require('react');
const {getFragment} = require('relay-runtime');

type ReturnType<TQuery: OperationType, TKey: ?{+$data?: mixed, ...}> = [
// NOTE: This $Call ensures that the type of the returned data is either:
// - nullable if the provided ref type is nullable
// - non-nullable if the provided ref type is non-nullable
// prettier-ignore
$Call<
& (<TFragmentData>( { +$data?: TFragmentData, ... }) => TFragmentData)
& (<TFragmentData>(?{ +$data?: TFragmentData, ... }) => ?TFragmentData),
TKey,
>,
RefetchFnDynamic<TQuery, TKey>,
];

function useRefetchableFragment<
TQuery: OperationType,
TKey: ?{+$data?: mixed, +$fragmentSpreads: FragmentType, ...},
TFragmentType: FragmentType,
TVariables: Variables,
TData,
TKey: ?{+$fragmentSpreads: TFragmentType, ...},
>(
fragmentInput: GraphQLTaggedNode,
fragmentInput: RefetchableFragment<TFragmentType, TData, TVariables>,
fragmentRef: TKey,
): ReturnType<TQuery, TKey> {
): ReturnType<TVariables, TData, TKey> {
const fragmentNode = getFragment(fragmentInput);
useStaticFragmentNodeWarning(
fragmentNode,
'first argument of useRefetchableFragment()',
);
const {fragmentData, refetch} = useRefetchableFragmentInternal<TQuery, TKey>(
fragmentNode,
fragmentRef,
'useRefetchableFragment()',
);
const {fragmentData, refetch} = useRefetchableFragmentInternal<
{variables: TVariables, response: TData},
{data?: TData},
>(fragmentNode, fragmentRef, 'useRefetchableFragment()');
if (__DEV__) {
// eslint-disable-next-line react-hooks/rules-of-hooks
useDebugValue({fragment: fragmentNode.name, data: fragmentData});
}
/* $FlowExpectedError[prop-missing] : Exposed options is a subset of internal
* options */
return [fragmentData, (refetch: RefetchFnDynamic<TQuery, TKey>)];
// $FlowFixMe[incompatible-return]
// $FlowFixMe[prop-missing]
return [fragmentData, refetch];
}

module.exports = useRefetchableFragment;
2 changes: 1 addition & 1 deletion packages/react-relay/relay-hooks/useRefetchableFragment.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export type RefetchFn<TVariables, TKey, TOptions = Options> = RefetchFnBase<
TOptions,
>;

type ReturnType<TVariables, TData, TKey> = [
export type ReturnType<TVariables, TData, TKey> = [
// NOTE: This $Call ensures that the type of the returned data is either:
// - nullable if the provided ref type is nullable
// - non-nullable if the provided ref type is non-nullable
Expand Down

0 comments on commit d9a099e

Please sign in to comment.