Skip to content

Instantly share code, notes, and snippets.

@sibelius
Created June 25, 2022 14:35
Show Gist options
  • Save sibelius/fe11f8553e3eb65caac39f8a585e7641 to your computer and use it in GitHub Desktop.
Save sibelius/fe11f8553e3eb65caac39f8a585e7641 to your computer and use it in GitHub Desktop.
Relay useMutationPromise.tsx
import { useState, useRef, useEffect } from 'react';
import type {
GraphQLTaggedNode } from 'relay-runtime';
import {
commitMutation as relayCommitMutation,
} from 'relay-runtime';
import { useRelayEnvironment } from 'react-relay';
type UseMutationPromiseArgs = {
mutation: GraphQLTaggedNode;
};
export const useMutationPromise = (args: UseMutationPromiseArgs) => {
const { mutation } = args;
const environment = useRelayEnvironment();
const [isPending, setPending] = useState<boolean>(false);
const requestRef = useRef(null);
const mountedRef = useRef(false);
const execute = (config) => {
return new Promise((resolve, reject) => {
if (requestRef.current != null) {
return reject('mutation pending');
}
const onCompleted = (payload, errors) => {
if (!mountedRef.current) {
return reject('mutation pending');
}
if (errors) {
reject(errors[0]);
return;
}
requestRef.current = null;
setPending(false);
resolve(payload);
};
const onError = (error) => {
if (!mountedRef.current) {
return reject('mutation pending');
}
requestRef.current = null;
setPending(false);
reject(error);
};
relayCommitMutation(environment, {
mutation,
variables: config.variables,
onCompleted,
onError,
});
requestRef.current = execute;
setPending(true);
});
};
useEffect(() => {
mountedRef.current = true;
return () => (mountedRef.current = false);
}, []);
return [execute, isPending];
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment