From 051e4694c20b6fa5a5a7a6d62e52f6a6a9919349 Mon Sep 17 00:00:00 2001 From: Andrey Lunyov Date: Fri, 18 Aug 2023 14:54:01 -0700 Subject: [PATCH] Update types of `useMutation` to use typed `graphql` tags Reviewed By: kassens Differential Revision: D48420982 fbshipit-source-id: b7863029ddf615ec61510dbfcf3b4b5967b0b3b1 --- .../multi-actor/__tests__/ActorChange-test.js | 6 ++- .../__tests__/ActorChangeWithMutation-test.js | 2 +- .../useMutation-fast-refresh-test.js | 10 ++--- .../relay-hooks/__tests__/useMutation-test.js | 2 +- .../react-relay/relay-hooks/useMutation.js | 43 +++++++++++++++---- 5 files changed, 44 insertions(+), 19 deletions(-) diff --git a/packages/react-relay/multi-actor/__tests__/ActorChange-test.js b/packages/react-relay/multi-actor/__tests__/ActorChange-test.js index 07f120bffb576..7196b99c87a80 100644 --- a/packages/react-relay/multi-actor/__tests__/ActorChange-test.js +++ b/packages/react-relay/multi-actor/__tests__/ActorChange-test.js @@ -131,7 +131,7 @@ type Props = $ReadOnly<{ function ActorMessage(props: Props) { const data = useFragment(fragment, props.myFragment); - const [commit] = useMutation<$FlowFixMe>(mutation); + const [commit] = useMutation(mutation); // We're calling this hook only to verify that it won't throw. // `useRelayActorEnvironment` should be able to have access to `getEnvironmentForActor` function @@ -146,7 +146,9 @@ function ActorMessage(props: Props) { onClick={() => commit({ variables: { - feedbackID: 'feedback:1234', + input: { + feedbackId: 'feedback:1234', + }, }, }) } diff --git a/packages/react-relay/multi-actor/__tests__/ActorChangeWithMutation-test.js b/packages/react-relay/multi-actor/__tests__/ActorChangeWithMutation-test.js index cddec48250bfb..48b837b61e715 100644 --- a/packages/react-relay/multi-actor/__tests__/ActorChangeWithMutation-test.js +++ b/packages/react-relay/multi-actor/__tests__/ActorChangeWithMutation-test.js @@ -144,7 +144,7 @@ type Props = $ReadOnly<{ function ActorComponent(props: Props) { const data = useFragment(fragment, props.fragmentKey); - const [commit] = useMutation(mutation); + const [commit] = useMutation(mutation); props.render({ id: data.id, diff --git a/packages/react-relay/relay-hooks/__tests__/useMutation-fast-refresh-test.js b/packages/react-relay/relay-hooks/__tests__/useMutation-fast-refresh-test.js index 8dc8780d862cb..7413cd3ab02f0 100644 --- a/packages/react-relay/relay-hooks/__tests__/useMutation-fast-refresh-test.js +++ b/packages/react-relay/relay-hooks/__tests__/useMutation-fast-refresh-test.js @@ -42,7 +42,7 @@ describe('useLazyLoadQueryNode', () => { const variables = { input: { - commentId: '', + feedbackId: '', }, }; beforeEach(() => { @@ -82,9 +82,7 @@ describe('useLazyLoadQueryNode', () => { ReactRefreshRuntime.injectIntoGlobalHook(global); let commit; const V1 = function (props: {}) { - const [commitFn, isMutationInFlight] = useMutation( - CommentCreateMutation, - ); + const [commitFn, isMutationInFlight] = useMutation(CommentCreateMutation); commit = commitFn; return isInFlightFn(isMutationInFlight); }; @@ -118,9 +116,7 @@ describe('useLazyLoadQueryNode', () => { // Trigger a fast fresh function V2(props: any) { - const [commitFn, isMutationInFlight] = useMutation( - CommentCreateMutation, - ); + const [commitFn, isMutationInFlight] = useMutation(CommentCreateMutation); commit = commitFn; return isInFlightFn(isMutationInFlight); } diff --git a/packages/react-relay/relay-hooks/__tests__/useMutation-test.js b/packages/react-relay/relay-hooks/__tests__/useMutation-test.js index dd280b182fe8d..4df992ffee7f8 100644 --- a/packages/react-relay/relay-hooks/__tests__/useMutation-test.js +++ b/packages/react-relay/relay-hooks/__tests__/useMutation-test.js @@ -94,7 +94,7 @@ beforeEach(() => { }) { const [mutation, setMutationFn] = useState(initialMutation); setMutation = setMutationFn; - const [commitFn, isMutationInFlight] = useMutation(mutation); + const [commitFn, isMutationInFlight] = useMutation(mutation); commit = (config: any) => ReactTestRenderer.act(() => { disposable = commitFn(config); diff --git a/packages/react-relay/relay-hooks/useMutation.js b/packages/react-relay/relay-hooks/useMutation.js index dd5ccc8e1397b..d7dfa82820748 100644 --- a/packages/react-relay/relay-hooks/useMutation.js +++ b/packages/react-relay/relay-hooks/useMutation.js @@ -14,13 +14,14 @@ import type { DeclarativeMutationConfig, Disposable, - GraphQLTaggedNode, IEnvironment, + Mutation, MutationConfig, MutationParameters, PayloadError, SelectorStoreUpdater, UploadableMap, + Variables, } from 'relay-runtime'; const useIsMountedRef = require('./useIsMountedRef'); @@ -50,13 +51,39 @@ export type UseMutationConfig = { variables: TMutation['variables'], }; -function useMutation( - mutation: GraphQLTaggedNode, +type UseMutationConfigInternal = { + configs?: Array, + onError?: ?(error: Error) => void, + onCompleted?: ?(response: TData, errors: ?Array) => void, + onNext?: ?() => void, + onUnsubscribe?: ?() => void, + optimisticResponse?: TRawResponse, + optimisticUpdater?: ?SelectorStoreUpdater, + updater?: ?SelectorStoreUpdater, + uploadables?: UploadableMap, + variables: TVariables, +}; + +function useMutation( + mutation: Mutation, commitMutationFn?: ( environment: IEnvironment, - config: MutationConfig, + config: MutationConfig<{ + variables: TVariables, + /* $FlowFixMe[incompatible-type-arg] error exposed when improving flow + * typing of useMutation */ + response: TData, + /* $FlowFixMe[incompatible-type-arg] error exposed when improving flow + * typing of useMutation */ + rawResponse?: TRawResponse, + }>, + /* $FlowFixMe[incompatible-type-arg] error exposed when improving flow typing + * of useMutation */ ) => Disposable = defaultCommitMutation, -): [(UseMutationConfig) => Disposable, boolean] { +): [ + (UseMutationConfigInternal) => Disposable, + boolean, +] { const environment = useRelayEnvironment(); const isMountedRef = useIsMountedRef(); const environmentRef = useRef(environment); @@ -94,18 +121,18 @@ function useMutation( }, [environment, isMountedRef, mutation]); const commit = useCallback( - (config: UseMutationConfig) => { + (config: UseMutationConfigInternal) => { if (isMountedRef.current) { setMutationInFlight(true); } const disposable: Disposable = commitMutationFn(environment, { ...config, mutation, - onCompleted: (response, errors) => { + onCompleted: (response: TData, errors: ?Array) => { cleanup(disposable); config.onCompleted?.(response, errors); }, - onError: error => { + onError: (error: Error) => { cleanup(disposable); config.onError?.(error); },