Skip to content

Commit

Permalink
Update types of useMutation to use typed graphql tags
Browse files Browse the repository at this point in the history
Reviewed By: kassens

Differential Revision: D48420982

fbshipit-source-id: b7863029ddf615ec61510dbfcf3b4b5967b0b3b1
  • Loading branch information
alunyov authored and facebook-github-bot committed Aug 18, 2023
1 parent 7ac172e commit 051e469
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -146,7 +146,9 @@ function ActorMessage(props: Props) {
onClick={() =>
commit({
variables: {
feedbackID: 'feedback:1234',
input: {
feedbackId: 'feedback:1234',
},
},
})
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ type Props = $ReadOnly<{

function ActorComponent(props: Props) {
const data = useFragment(fragment, props.fragmentKey);
const [commit] = useMutation<ActorChangeWithMutationTestMutation>(mutation);
const [commit] = useMutation(mutation);

props.render({
id: data.id,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ describe('useLazyLoadQueryNode', () => {

const variables = {
input: {
commentId: '<id>',
feedbackId: '<id>',
},
};
beforeEach(() => {
Expand Down Expand Up @@ -82,9 +82,7 @@ describe('useLazyLoadQueryNode', () => {
ReactRefreshRuntime.injectIntoGlobalHook(global);
let commit;
const V1 = function (props: {}) {
const [commitFn, isMutationInFlight] = useMutation<any>(
CommentCreateMutation,
);
const [commitFn, isMutationInFlight] = useMutation(CommentCreateMutation);
commit = commitFn;
return isInFlightFn(isMutationInFlight);
};
Expand Down Expand Up @@ -118,9 +116,7 @@ describe('useLazyLoadQueryNode', () => {

// Trigger a fast fresh
function V2(props: any) {
const [commitFn, isMutationInFlight] = useMutation<any>(
CommentCreateMutation,
);
const [commitFn, isMutationInFlight] = useMutation(CommentCreateMutation);
commit = commitFn;
return isInFlightFn(isMutationInFlight);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ beforeEach(() => {
}) {
const [mutation, setMutationFn] = useState(initialMutation);
setMutation = setMutationFn;
const [commitFn, isMutationInFlight] = useMutation<any>(mutation);
const [commitFn, isMutationInFlight] = useMutation(mutation);
commit = (config: any) =>
ReactTestRenderer.act(() => {
disposable = commitFn(config);
Expand Down
43 changes: 35 additions & 8 deletions packages/react-relay/relay-hooks/useMutation.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@
import type {
DeclarativeMutationConfig,
Disposable,
GraphQLTaggedNode,
IEnvironment,
Mutation,
MutationConfig,
MutationParameters,
PayloadError,
SelectorStoreUpdater,
UploadableMap,
Variables,
} from 'relay-runtime';

const useIsMountedRef = require('./useIsMountedRef');
Expand Down Expand Up @@ -50,13 +51,39 @@ export type UseMutationConfig<TMutation: MutationParameters> = {
variables: TMutation['variables'],
};

function useMutation<TMutation: MutationParameters>(
mutation: GraphQLTaggedNode,
type UseMutationConfigInternal<TVariables, TData, TRawResponse> = {
configs?: Array<DeclarativeMutationConfig>,
onError?: ?(error: Error) => void,
onCompleted?: ?(response: TData, errors: ?Array<PayloadError>) => void,
onNext?: ?() => void,
onUnsubscribe?: ?() => void,
optimisticResponse?: TRawResponse,
optimisticUpdater?: ?SelectorStoreUpdater<TData>,
updater?: ?SelectorStoreUpdater<TData>,
uploadables?: UploadableMap,
variables: TVariables,
};

function useMutation<TVariables: Variables, TData, TRawResponse = {...}>(
mutation: Mutation<TVariables, TData, TRawResponse>,
commitMutationFn?: (
environment: IEnvironment,
config: MutationConfig<TMutation>,
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<TMutation>) => Disposable, boolean] {
): [
(UseMutationConfigInternal<TVariables, TData, TRawResponse>) => Disposable,
boolean,
] {
const environment = useRelayEnvironment();
const isMountedRef = useIsMountedRef();
const environmentRef = useRef(environment);
Expand Down Expand Up @@ -94,18 +121,18 @@ function useMutation<TMutation: MutationParameters>(
}, [environment, isMountedRef, mutation]);

const commit = useCallback(
(config: UseMutationConfig<TMutation>) => {
(config: UseMutationConfigInternal<TVariables, TData, TRawResponse>) => {
if (isMountedRef.current) {
setMutationInFlight(true);
}
const disposable: Disposable = commitMutationFn(environment, {
...config,
mutation,
onCompleted: (response, errors) => {
onCompleted: (response: TData, errors: ?Array<PayloadError>) => {
cleanup(disposable);
config.onCompleted?.(response, errors);
},
onError: error => {
onError: (error: Error) => {
cleanup(disposable);
config.onError?.(error);
},
Expand Down

0 comments on commit 051e469

Please sign in to comment.