react-query#useMutation TypeScript Examples
The following examples show how to use
react-query#useMutation.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: useCreateAddress.ts From wildduck-ui with MIT License | 8 votes |
useCreateAddress = () => {
const queryClient = useQueryClient();
return useMutation(
({ userId, addressDetails }: IProp) => api.addressApi.createUserAddress(userId, addressDetails),
{
onError: () => {
AppEvents.publish(Events.Error, 'Error');
},
onSuccess: ({ data }) => {
handleError(data);
queryClient.invalidateQueries('useAddress');
},
},
);
}
Example #2
Source File: index.tsx From RareCamp with Apache License 2.0 | 6 votes |
AccountMenu = () => {
const router = useRouter()
const mutation = useMutation(() => Auth.signOut({ global: true }), {
onSuccess: router.reload,
onError: (err: Error) =>
notification.error({
message: 'Can not logout',
description: err.message,
placement: 'topRight',
duration: 1.5,
}),
})
return (
<OFMenu>
<Menu.Item>
<Link href="/auth/password">Update Password</Link>
</Menu.Item>
<Menu.Item>
<Button
loading={mutation.isLoading}
onClick={() => mutation.mutate()}
>
Logout
</Button>
</Menu.Item>
</OFMenu>
)
}
Example #3
Source File: useApiMutation.ts From kinopub.webos with MIT License | 6 votes |
function useApiMutation<TMethod extends Method, TData = Methods[TMethod], TError = string, TVariables = Parameters<ApiClient[TMethod]>>(
method: TMethod,
) {
const client = useMemo(() => new ApiClient(), []);
// @ts-expect-error
const mutation = useMutation<TData, TError, TVariables>([client, method], (params) => client[method](...params));
return Object.assign({}, mutation, {
[method]: mutation.mutate,
[`${method}Async`]: mutation.mutateAsync,
});
}
Example #4
Source File: useMutateResource.ts From ke with MIT License | 6 votes |
export function useMutateResource<ResourceData, SourceData, TError = unknown, TContext = unknown>(
userConfigOrKey: ResourceOptionsOrKey<MutateResourceOptions<ResourceData, SourceData, TError, TContext>>,
requestOptions: MutationOptions<ResourceData, SourceData, TError, TContext> = {}
): MutationResult<ResourceData, SourceData, TError, TContext> {
const userConfig = useConfigResolver(userConfigOrKey)
const {
mutate: { fn },
} = useDefaultResourceConfig<ResourceData, SourceData>()
const { key, ...options } = userConfig
const { requestConfig, overrideGlobalOnError, mutationFn, ...mutationOptions } = deepmerge(options, requestOptions)
const queryClient = useQueryClient()
const globalOnError = queryClient.getDefaultOptions()?.mutations?.onError
if (!!mutationOptions.onError && globalOnError && !overrideGlobalOnError) {
mutationOptions.onError = injectInCallback(mutationOptions.onError, globalOnError)
}
const mutateFunction = mutationFn || ((data: SourceData) => fn(key, data, requestConfig))
return useMutation<ResourceData, TError, SourceData, TContext>(
mutateFunction,
mutationOptions as UseMutationOptions<ResourceData, TError, SourceData, TContext>
)
}
Example #5
Source File: usePersistentContext.ts From apps with GNU Affero General Public License v3.0 | 6 votes |
export default function usePersistentContext<T>(
key: string,
valueWhenCacheEmpty?: T,
validValues?: T[],
fallbackValue?: T,
): [T, (value: T) => Promise<void>, boolean] {
const queryKey = [key, valueWhenCacheEmpty];
const queryClient = useQueryClient();
const { data, isFetched } = useQuery<unknown, unknown, T>(queryKey, () =>
getAsyncCache<T>(key, valueWhenCacheEmpty, validValues),
);
const { mutateAsync: updateValue } = useMutation<void, unknown, unknown, T>(
(value: T) => setCache(key, value),
{
onMutate: (mutatedData) => {
const current = data;
queryClient.setQueryData(queryKey, mutatedData);
return current;
},
onError: (_, __, rollback) => {
queryClient.setQueryData(queryKey, rollback);
},
},
);
return [data ?? fallbackValue, updateValue, isFetched];
}
Example #6
Source File: bookmark-hooks.tsx From nyxo-website with MIT License | 6 votes |
useDeleteBookmark = () => {
return useMutation(removeBookmark, {
onSuccess: ({ slug }, { type }) =>
queryCache.setQueryData([type, { slug: slug }], {
bookmarked: false,
id: "",
}),
})
}
Example #7
Source File: api.ts From mui-toolpad with MIT License | 6 votes |
function createClient<D extends MethodsOf<any>>(endpoint: string): ApiClient<D> {
const query = createFetcher(endpoint, 'query');
const mutation = createFetcher(endpoint, 'mutation');
return {
query,
mutation,
useQuery: (key, params, options) => {
return useQuery({
...options,
enabled: !!params,
queryKey: [key, params],
queryFn: () => {
if (!params) {
throw new Error(`Invariant: "enabled" prop of useQuery should prevent this call'`);
}
return query[key](...params);
},
});
},
useMutation: (key, options) => useMutation((params) => mutation[key](...params), options),
refetchQueries(key, params?) {
return queryClient.refetchQueries(params ? [key, params] : [key]);
},
};
}
Example #8
Source File: donation.ts From frontend with MIT License | 6 votes |
export function useDonationSession() {
const { t } = useTranslation()
const mutation = useMutation<
AxiosResponse<CheckoutSessionResponse>,
AxiosError<ApiErrors>,
CheckoutSessionInput
>({
mutationFn: createCheckoutSession,
onError: () => AlertStore.show(t('common:alerts.error'), 'error'),
onSuccess: () => AlertStore.show(t('common:alerts.message-sent'), 'success'),
})
return mutation
}
Example #9
Source File: useCreateAllowedDomain.ts From wildduck-ui with MIT License | 6 votes |
useCreateAllowedDomain = () => {
const queryClient = useQueryClient();
return useMutation(
(domain: { tag: string; domain: string }) =>
api.domainAccessApi.createAllowedDomain(domain.tag, { domain: domain.domain }),
{
onSuccess: () => {
AppEvents.publish(Events.Success, 'Success');
queryClient.invalidateQueries('query-allowList');
queryClient.invalidateQueries('query-blockList');
},
onError: () => {
AppEvents.publish(Events.Error, 'Error');
},
},
);
}
Example #10
Source File: password.tsx From RareCamp with Apache License 2.0 | 5 votes |
export default function App() {
const router = useRouter()
const mutation = useMutation(
({ username }: { username: string }) =>
Auth.forgotPassword(username),
{
onSuccess: async (_, variables) => {
notification.success({
message: 'Instructions sent to your emails',
description: 'Account confirmed successfully!',
placement: 'topRight',
duration: 1.5,
})
await router.push(
`/auth/resetpassword?username=${variables.username}`,
)
},
onError: async (err: Error) => {
notification.error({
message: 'User confirmation failed',
description: err.message,
placement: 'topRight',
duration: 3,
})
},
},
)
return (
<AuthLayout>
<div>
<Title level={3}>Forgot your password?</Title>
<p>
We'll send you an email with instructions.
<p>
or
<Button
type="link"
onClick={() => router.push('/auth/login')}
>
Login
</Button>
</p>
</p>
</div>
<Form
layout="vertical"
name="forgot_password_form"
onFinish={mutation.mutate}
>
<Form.Item
label={<span style={{ fontWeight: 500 }}>Email</span>}
name="username"
required={false}
rules={[
{
required: true,
message: 'Please input your email',
type: 'email',
},
]}
>
<Input placeholder="[email protected]" />
</Form.Item>
<Form.Item>
<Button
loading={mutation.isLoading}
type="primary"
htmlType="submit"
block
className="login-form-button"
>
Reset Password
</Button>
</Form.Item>
</Form>
</AuthLayout>
)
}
Example #11
Source File: index.tsx From strapi-plugin-comments with MIT License | 5 votes |
DiscussionThreadItemApprovalFlowActions = ({
id,
allowedActions: { canModerate },
queryToInvalidate,
}) => {
const toggleNotification = useNotification();
const queryClient = useQueryClient();
const { lockApp, unlockApp } = useOverlayBlocker();
const onSuccess = (message) => async () => {
if (queryToInvalidate) {
await queryClient.invalidateQueries(queryToInvalidate);
}
toggleNotification({
type: "success",
message: `${pluginId}.${message}`,
});
unlockApp();
};
const onError = (err) => {
handleAPIError(err, toggleNotification);
};
const approveItemMutation = useMutation(approveItem, {
onSuccess: onSuccess(
"page.details.actions.comment.approve.confirmation.success"
),
onError,
refetchActive: false,
});
const rejectItemMutation = useMutation(rejectItem, {
onSuccess: onSuccess(
"page.details.actions.comment.reject.confirmation.success"
),
onError,
refetchActive: false,
});
const handleApproveClick = () => {
if (canModerate) {
lockApp();
approveItemMutation.mutate(id);
}
};
const handleRejectClick = () => {
if (canModerate) {
lockApp();
rejectItemMutation.mutate(id);
}
};
if (canModerate) {
return (
<>
<IconButton
icon={<Check />}
label={getMessage("page.details.actions.comment.approve", "Approve")}
onClick={handleApproveClick}
/>
<IconButton
icon={<Cross />}
label={getMessage("page.details.actions.comment.reject", "Reject")}
onClick={handleRejectClick}
/>
</>
);
}
return null;
}
Example #12
Source File: Manual.tsx From NextPay with MIT License | 5 votes |
Manual = ({ max, min }: { max: number; min: number }) => {
const [amount, setAmount] = useState<number>(Math.max(0, min));
const [isCopied, copy] = useCopyClipboard({ successDuration: 3000 });
const mutation = useMutation(getInvoice);
if (mutation.error) {
return <div>Error getting invoice. Please try again</div>;
}
if (mutation.data?.pr) {
return (
<>
<IndexStyles.copyButton onClick={() => copy(mutation.data.pr)}>
{isCopied ? (
<IndexStyles.copySuccess>Copied</IndexStyles.copySuccess>
) : (
<IndexStyles.copy>Click QR to copy</IndexStyles.copy>
)}
<QRcode value={mutation.data.pr} size={240} />
</IndexStyles.copyButton>
<IndexStyles.info>Scan with any lightning wallet</IndexStyles.info>
</>
);
}
return (
<>
<S.separation>
<S.singleLine>
<S.darkTitle>Max</S.darkTitle>
<div>{`${max} sats`}</div>
</S.singleLine>
<S.singleLine>
<S.darkTitle>Min</S.darkTitle>
<div>{`${min} sats`}</div>
</S.singleLine>
</S.separation>
<S.singleLine>
<S.darkTitle>Amount</S.darkTitle>
<div>{`${amount} sats`}</div>
</S.singleLine>
<S.input
onBlur={() => {
if (amount < min) {
setAmount(min);
} else if (amount > max) {
setAmount(max);
}
}}
placeholder={'Sats'}
value={amount}
type={'number'}
onChange={e => setAmount(Number(e.target.value))}
/>
<S.button
disabled={mutation.isLoading}
onClick={() => mutation.mutate({ amount })}
>
Get Invoice
</S.button>
</>
);
}
Example #13
Source File: EmailLogin.tsx From vsinder with Apache License 2.0 | 5 votes |
EmailLogin: React.FC<AuthStackNav<"EmailLogin">> = ({
navigation,
}) => {
const [mutate, { isLoading }] = useMutation(defaultMutationFn);
return (
<ScreenWrapper>
<KeyboardAwareScrollView keyboardShouldPersistTaps="handled">
<Formik
validationSchema={schema}
validateOnBlur={false}
validateOnChange={false}
initialValues={{ email: "", password: "" }}
onSubmit={async (values) => {
const tokens = await mutate(["/email/login", values, "POST"]);
navigation.navigate("tokens", tokens);
}}
>
{({ handleSubmit }) => (
<>
<FormSpacer>
<TextField
label="Email"
textContentType="emailAddress"
autoCapitalize="none"
name="email"
/>
</FormSpacer>
<FormSpacer>
<TextField
autoCapitalize="none"
label="Password"
secureTextEntry
textContentType="password"
name="password"
/>
</FormSpacer>
<LoadingButton
isLoading={isLoading}
onPress={() => handleSubmit()}
>
Login
</LoadingButton>
</>
)}
</Formik>
</KeyboardAwareScrollView>
</ScreenWrapper>
);
}
Example #14
Source File: EmailLogin.tsx From vsinder-app with Apache License 2.0 | 5 votes |
EmailLogin: React.FC<AuthStackNav<"EmailLogin">> = ({
navigation,
}) => {
const [mutate, { isLoading }] = useMutation(defaultMutationFn);
return (
<ScreenWrapper>
<KeyboardAwareScrollView keyboardShouldPersistTaps="handled">
<Formik
validationSchema={schema}
validateOnBlur={false}
validateOnChange={false}
initialValues={{ email: "", password: "" }}
onSubmit={async (values) => {
const tokens = await mutate(["/email/login", values, "POST"]);
navigation.navigate("tokens", tokens);
}}
>
{({ handleSubmit }) => (
<>
<FormSpacer>
<TextField
label="email"
textContentType="emailAddress"
autoCapitalize="none"
name="email"
/>
</FormSpacer>
<FormSpacer>
<TextField
autoCapitalize="none"
label="password"
secureTextEntry
textContentType="password"
name="password"
/>
</FormSpacer>
<LoadingButton
isLoading={isLoading}
onPress={() => handleSubmit()}
>
login
</LoadingButton>
</>
)}
</Formik>
</KeyboardAwareScrollView>
</ScreenWrapper>
);
}
Example #15
Source File: useDropAllExpired.ts From homebase-app with MIT License | 5 votes |
useDropAllExpired = () => {
const queryClient = useQueryClient();
const openNotification = useNotification();
const { network, tezos, account, connect } = useTezos();
return useMutation<
any | Error,
Error,
{ dao: BaseDAO; expiredProposalIds: string[] }
>(
async (params) => {
const { key: dropNotification, closeSnackbar: closeFlushNotification } =
openNotification({
message: "Please sign the transaction to drop all expired proposals",
persist: true,
variant: "info",
});
try {
let tezosToolkit = tezos;
if (!account) {
tezosToolkit = await connect();
}
const data = await params.dao.dropAllExpired(
params.expiredProposalIds,
tezosToolkit
);
closeFlushNotification(dropNotification);
await data.confirmation(1);
openNotification({
message: "Execute transaction confirmed!",
autoHideDuration: 5000,
variant: "success",
detailsLink: `https://${networkNameMap[network]}.tzkt.io/` + data.opHash,
});
return data;
} catch (e) {
closeFlushNotification(dropNotification);
openNotification({
message: "An error has happened with execute transaction!",
variant: "error",
autoHideDuration: 5000,
});
return new Error((e as Error).message);
}
},
{
onSuccess: () => {
queryClient.resetQueries();
},
}
);
}
Example #16
Source File: useSettingsMigration.ts From apps with GNU Affero General Public License v3.0 | 5 votes |
export default function useSettingsMigration(
user: LoggedUser,
tokenRefreshed: boolean,
): UseSettingsMigrationRet {
const [migrationCompleted, setMigrationCompleted] = useState(false);
const [settings, setSettings] = useState<SettingsV2>();
const [postpone, setPostpone] = usePersistentState(
'postponeSettingsMigration',
null,
POSTPONE_DONT,
);
const [migrateAfterSignIn, setMigrateAfterSignIn] = usePersistentState(
'migrateAfterSignIn',
false,
false,
);
const { mutateAsync: migrate, isLoading: isMigrating } = useMutation(
() =>
request(`${apiUrl}/graphql`, generateQuery(settings), {
bookmarks: {
postIds:
settings?.state?.feed?.bookmarks?.map?.((post) => post.id) ?? [],
},
filters: {
includeTags: objectToEnabledKeys(settings?.state?.feed?.enabledTags),
excludeSources: objectToEnabledKeys(
settings?.state?.feed?.disabledPublications,
),
},
}),
{
onSuccess: async () => {
await setSettings(null);
await browser.storage.local.set({ [SETTINGS_V2_KEY]: {} });
setMigrationCompleted(true);
},
},
);
useEffect(() => {
browser.storage.local.get(SETTINGS_V2_KEY).then(setSettings);
}, []);
const hasSettings = checkIfHasSettings(settings);
useEffect(() => {
if (user && tokenRefreshed && migrateAfterSignIn && hasSettings) {
migrate();
}
}, [user, tokenRefreshed, migrateAfterSignIn, hasSettings]);
return {
hasSettings,
showMigrationModal:
hasSettings &&
!migrateAfterSignIn &&
postpone !== null &&
((!user && postpone !== POSTPONE_ANONYMOUS) ||
(user && postpone !== POSTPONE_LOGGED_IN)),
migrateAfterSignIn: () => setMigrateAfterSignIn(true),
postponeMigration: () => {
if (user) {
return setPostpone(POSTPONE_LOGGED_IN);
}
return setPostpone(POSTPONE_ANONYMOUS);
},
ackMigrationCompleted: () => setMigrationCompleted(false),
forceMigrationModal: () => setPostpone(POSTPONE_DONT),
isMigrating,
migrationCompleted,
migrate,
postponed: hasSettings && postpone !== null && postpone !== POSTPONE_DONT,
};
}
Example #17
Source File: useCoaching.ts From nyxo-app with GNU General Public License v3.0 | 5 votes |
useCreateCoaching = () => {
return useMutation(createCoaching)
}
Example #18
Source File: useCoaching.ts From nyxo-website with MIT License | 5 votes |
useCreateCoaching = () => {
return useMutation(createCoaching)
}
Example #19
Source File: index.tsx From interbtc-ui with Apache License 2.0 | 5 votes |
ClaimRewardsButton = ({
className,
claimableRewardAmount,
...rest
}: CustomProps & InterlayDenimOrKintsugiMidnightContainedButtonProps): JSX.Element => {
const { address } = useSelector((state: StoreType) => state.general);
const queryClient = useQueryClient();
const claimRewardsMutation = useMutation<void, Error, void>(
() => {
return window.bridge.escrow.withdrawRewards();
},
{
onSuccess: () => {
queryClient.invalidateQueries([GENERIC_FETCHER, 'escrow', 'getRewardEstimate', address]);
queryClient.invalidateQueries([GENERIC_FETCHER, 'escrow', 'getRewards', address]);
}
}
);
const handleClaimRewards = () => {
claimRewardsMutation.mutate();
};
return (
<>
<InterlayDenimOrKintsugiSupernovaContainedButton
className={clsx('w-full', 'px-6', 'py-3', 'text-base', 'rounded-md', className)}
onClick={handleClaimRewards}
pending={claimRewardsMutation.isLoading}
{...rest}
>
Claim {claimableRewardAmount} {GOVERNANCE_TOKEN_SYMBOL} Rewards
</InterlayDenimOrKintsugiSupernovaContainedButton>
{claimRewardsMutation.isError && (
<ErrorModal
open={claimRewardsMutation.isError}
onClose={() => {
claimRewardsMutation.reset();
}}
title='Error'
description={claimRewardsMutation.error?.message || ''}
/>
)}
</>
);
}
Example #20
Source File: UpdateBirthdayModal.tsx From frontend with MIT License | 5 votes |
function UpdateBirthdayModal({
isOpen,
handleClose,
person,
}: {
isOpen: boolean
handleClose: (data?: Person) => void
person: UpdatePerson
}) {
const { t } = useTranslation()
const dateBefore18Years = new Date(new Date().setFullYear(new Date().getFullYear() - 18))
const initialValues: BirthdayFormData = {
birthday: format(new Date(person.birthday ?? dateBefore18Years), formatString),
}
const mutation = useMutation<AxiosResponse<Person>, AxiosError<ApiErrors>, UpdatePerson>({
mutationFn: updateCurrentPerson(),
onError: () => AlertStore.show(t('common:alerts.error'), 'error'),
onSuccess: () => AlertStore.show(t('common:alerts.success'), 'success'),
})
const onSubmit = async (
values: BirthdayFormData,
{ setFieldError }: FormikHelpers<BirthdayFormData>,
) => {
try {
const birthDate = new Date(values?.birthday)
await mutation.mutateAsync({ ...person, birthday: birthDate }).then((data) => {
handleClose(data.data)
})
} catch (error) {
console.error(error)
if (isAxiosError(error)) {
const { response } = error as AxiosError<ApiErrors>
response?.data.message.map(({ property, constraints }) => {
setFieldError(property, t(matchValidator(constraints)))
})
}
}
}
return (
<StyledModal
open={isOpen}
onClose={() => handleClose()}
aria-labelledby="modal-modal-title"
aria-describedby="modal-modal-description">
<Box className={classes.modal}>
<IconButton className={classes.close} onClick={() => handleClose()}>
<CloseIcon />
</IconButton>
<h2>Обнови рожден ден</h2>
<GenericForm<BirthdayFormData>
onSubmit={onSubmit}
initialValues={initialValues}
validationSchema={validationSchema}>
<Grid container spacing={3}>
<Grid item xs={12} sm={8}>
<FormTextField
type="date"
name="birthday"
label="Кога е твоят рожден ден?"
InputLabelProps={{
shrink: true,
}}
/>
</Grid>
<Grid item xs={6}>
<SubmitButton fullWidth />
</Grid>
</Grid>
</GenericForm>
</Box>
</StyledModal>
)
}
Example #21
Source File: index.tsx From RareCamp with Apache License 2.0 | 4 votes |
export default function ContactServiceProviderModal({
visible,
hide,
serviceProvider,
task,
}) {
const contactMutation = useMutation(
(message) =>
axios.post(
`/projects/${task.projectId}/tasks/${task.taskId}/contactUs`,
{ message, task, spName: serviceProvider.name },
),
{
onSuccess: async () => {
notification.success({
duration: 2,
message: `Message has been sent successfully`,
})
},
onError: (err: Error) =>
notification.error({
duration: 2,
message: `Message was not sent`,
description: err.message,
}),
},
)
const onFinish = ({ message }) => contactMutation.mutate(message)
return (
<Modal
centered
visible={visible}
footer={null}
onOk={hide}
onCancel={hide}
width={850}
>
<Row gutter={[60, 60]}>
<Col span={10}>
<Space
size={8}
style={{ textAlign: 'center' }}
direction="vertical"
>
<img
width="337px"
src="/OPenGT-contact-service-provider.png"
alt="OPenGT contact service provider "
/>
<h3 style={{ color: '#3e3465' }}>
We are here to help you move along
</h3>
<p>
We will meet with you to understand where you are and
help you move along to the next step
</p>
</Space>
</Col>
<Col span={14}>
<Space
direction="vertical"
style={{ width: '100%', height: '100%' }}
>
<h1>
Send Message to
{` ${serviceProvider.name}`}
</h1>
<b>Briefly describe what you want to discuss</b>
<Form layout="vertical" onFinish={onFinish}>
<Form.Item
name="message"
required={false}
rules={[
{
required: true,
message: 'Please input your message',
},
]}
>
<Input.TextArea
style={{ height: 238 }}
rows={8}
required={false}
/>
</Form.Item>
<Button
loading={contactMutation.isLoading}
block
htmlType="submit"
type="primary"
>
Send
</Button>
</Form>
</Space>
</Col>
</Row>
</Modal>
)
}