diff --git a/frontend/src/metabase/account/profile/components/UserProfileForm/UserProfileForm.unit.spec.tsx b/frontend/src/metabase/account/profile/components/UserProfileForm/UserProfileForm.unit.spec.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..93062cec8fbd02563a5be611aecdac51609b8f19
--- /dev/null
+++ b/frontend/src/metabase/account/profile/components/UserProfileForm/UserProfileForm.unit.spec.tsx
@@ -0,0 +1,30 @@
+import React from "react";
+import { render, screen } from "@testing-library/react";
+import userEvent from "@testing-library/user-event";
+import { createMockUser } from "metabase-types/api/mocks";
+import UserProfileForm, { UserProfileFormProps } from "./UserProfileForm";
+
+describe("UserProfileForm", () => {
+  it("should show a success message after form submit", async () => {
+    const props = getProps({
+      onSubmit: jest.fn().mockResolvedValue({}),
+    });
+
+    render(<UserProfileForm {...props} />);
+    userEvent.clear(screen.getByLabelText("First name"));
+    userEvent.type(screen.getByLabelText("First name"), "New name");
+    userEvent.click(screen.getByText("Update"));
+
+    expect(await screen.findByText("Success")).toBeInTheDocument();
+  });
+});
+
+const getProps = (
+  opts?: Partial<UserProfileFormProps>,
+): UserProfileFormProps => ({
+  user: createMockUser(),
+  locales: null,
+  isSsoUser: false,
+  onSubmit: jest.fn(),
+  ...opts,
+});
diff --git a/frontend/src/metabase/core/components/FormProvider/FormProvider.tsx b/frontend/src/metabase/core/components/FormProvider/FormProvider.tsx
index 8da14f4c29bcdfe1ea1de20a7446fc3476ea6f07..f31fdf266f02b60af19b1a882ab9557cbfbfcf39 100644
--- a/frontend/src/metabase/core/components/FormProvider/FormProvider.tsx
+++ b/frontend/src/metabase/core/components/FormProvider/FormProvider.tsx
@@ -4,6 +4,7 @@ import type { FormikConfig } from "formik";
 import type { AnySchema } from "yup";
 import useFormSubmit from "metabase/core/hooks/use-form-submit";
 import useFormValidation from "metabase/core/hooks/use-form-validation";
+import FormContext from "metabase/core/context/FormContext";
 
 export interface FormProviderProps<T, C> extends FormikConfig<T> {
   validationSchema?: AnySchema;
@@ -17,7 +18,7 @@ function FormProvider<T, C>({
   onSubmit,
   ...props
 }: FormProviderProps<T, C>): JSX.Element {
-  const { handleSubmit } = useFormSubmit({ onSubmit });
+  const { state, handleSubmit } = useFormSubmit({ onSubmit });
   const { initialErrors, handleValidate } = useFormValidation({
     initialValues,
     validationSchema,
@@ -25,13 +26,15 @@ function FormProvider<T, C>({
   });
 
   return (
-    <Formik
-      initialValues={initialValues}
-      initialErrors={initialErrors}
-      validate={handleValidate}
-      onSubmit={handleSubmit}
-      {...props}
-    />
+    <FormContext.Provider value={state}>
+      <Formik
+        initialValues={initialValues}
+        initialErrors={initialErrors}
+        validate={handleValidate}
+        onSubmit={handleSubmit}
+        {...props}
+      />
+    </FormContext.Provider>
   );
 }
 
diff --git a/frontend/src/metabase/core/components/FormSubmitButton/FormSubmitButton.tsx b/frontend/src/metabase/core/components/FormSubmitButton/FormSubmitButton.tsx
index f0db016acc67fe6f5e810d602f9718d13a8846a7..05a1bff5f6eb972482f42ad383ae9a3477bd751c 100644
--- a/frontend/src/metabase/core/components/FormSubmitButton/FormSubmitButton.tsx
+++ b/frontend/src/metabase/core/components/FormSubmitButton/FormSubmitButton.tsx
@@ -1,8 +1,8 @@
 import React, { forwardRef, Ref } from "react";
 import { t } from "ttag";
 import Button, { ButtonProps } from "metabase/core/components/Button";
-import { FormStatus } from "metabase/core/hooks/use-form-state";
 import useFormSubmitButton from "metabase/core/hooks/use-form-submit-button";
+import { FormStatus } from "metabase/core/context/FormContext";
 
 export interface FormSubmitButtonProps extends Omit<ButtonProps, "children"> {
   title?: string;
diff --git a/frontend/src/metabase/core/hooks/use-form-state/types.ts b/frontend/src/metabase/core/context/FormContext/FormContext.tsx
similarity index 51%
rename from frontend/src/metabase/core/hooks/use-form-state/types.ts
rename to frontend/src/metabase/core/context/FormContext/FormContext.tsx
index 97088e2d977fde10fae0b873ae447212debd7103..52ce9ac203dcd2aaff989537758936a2439f1ff9 100644
--- a/frontend/src/metabase/core/hooks/use-form-state/types.ts
+++ b/frontend/src/metabase/core/context/FormContext/FormContext.tsx
@@ -1,6 +1,14 @@
+import { createContext } from "react";
+
 export type FormStatus = "idle" | "pending" | "fulfilled" | "rejected";
 
 export interface FormState {
   status: FormStatus;
   message?: string;
 }
+
+const FormContext = createContext<FormState>({
+  status: "idle",
+});
+
+export default FormContext;
diff --git a/frontend/src/metabase/core/context/FormContext/index.ts b/frontend/src/metabase/core/context/FormContext/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f0857a740f261244e7689ddde8c8fa56df52e3d7
--- /dev/null
+++ b/frontend/src/metabase/core/context/FormContext/index.ts
@@ -0,0 +1,2 @@
+export { default } from "./FormContext";
+export type { FormState, FormStatus } from "./FormContext";
diff --git a/frontend/src/metabase/core/hooks/use-form-context/index.ts b/frontend/src/metabase/core/hooks/use-form-context/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..81a70f12e77bf6792432090fcbd63f3ce1d1c2fe
--- /dev/null
+++ b/frontend/src/metabase/core/hooks/use-form-context/index.ts
@@ -0,0 +1,2 @@
+export { default } from "./use-form-context";
+export type { FormState, FormStatus } from "metabase/core/context/FormContext";
diff --git a/frontend/src/metabase/core/hooks/use-form-context/use-form-context.ts b/frontend/src/metabase/core/hooks/use-form-context/use-form-context.ts
new file mode 100644
index 0000000000000000000000000000000000000000..eb6b5680b8d660be311546ab7582f4089f6f41ca
--- /dev/null
+++ b/frontend/src/metabase/core/hooks/use-form-context/use-form-context.ts
@@ -0,0 +1,8 @@
+import { useContext } from "react";
+import FormContext, { FormState } from "metabase/core/context/FormContext";
+
+const useFormContext = (): FormState => {
+  return useContext(FormContext);
+};
+
+export default useFormContext;
diff --git a/frontend/src/metabase/core/hooks/use-form-error-message/use-form-error-message.ts b/frontend/src/metabase/core/hooks/use-form-error-message/use-form-error-message.ts
index 2c913214e507146ac0a39ebd0ecc984bd5dc8fa9..ade7aa8e6d783b30ce93fc16cf750758bb300277 100644
--- a/frontend/src/metabase/core/hooks/use-form-error-message/use-form-error-message.ts
+++ b/frontend/src/metabase/core/hooks/use-form-error-message/use-form-error-message.ts
@@ -1,11 +1,11 @@
 import { useLayoutEffect, useState } from "react";
 import { useFormikContext } from "formik";
 import { t } from "ttag";
-import useFormState from "metabase/core/hooks/use-form-state";
+import useFormContext from "metabase/core/hooks/use-form-context";
 
 const useFormErrorMessage = (): string | undefined => {
   const { values, errors } = useFormikContext();
-  const { status, message } = useFormState();
+  const { status, message } = useFormContext();
   const [isVisible, setIsVisible] = useState(false);
   const hasErrors = Object.keys(errors).length > 0;
 
diff --git a/frontend/src/metabase/core/hooks/use-form-state/index.ts b/frontend/src/metabase/core/hooks/use-form-state/index.ts
deleted file mode 100644
index 1acef3bdec7d548ce1afe8f733c52d6979c9fb74..0000000000000000000000000000000000000000
--- a/frontend/src/metabase/core/hooks/use-form-state/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export { default } from "./use-form-state";
-export type { FormState, FormStatus } from "./types";
diff --git a/frontend/src/metabase/core/hooks/use-form-state/use-form-state.ts b/frontend/src/metabase/core/hooks/use-form-state/use-form-state.ts
deleted file mode 100644
index 14bca0a64e3f6f8eda9045fc8d4038590f17bee2..0000000000000000000000000000000000000000
--- a/frontend/src/metabase/core/hooks/use-form-state/use-form-state.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { useFormikContext } from "formik";
-import { FormState } from "./types";
-
-const DEFAULT_STATE: FormState = {
-  status: "idle",
-};
-
-const useFormState = (): FormState => {
-  const { status } = useFormikContext();
-  return status ?? DEFAULT_STATE;
-};
-
-export default useFormState;
diff --git a/frontend/src/metabase/core/hooks/use-form-submit-button/use-form-submit-button.ts b/frontend/src/metabase/core/hooks/use-form-submit-button/use-form-submit-button.ts
index 00661433ab1482cafa4f23f09bf3b1a5f43e1c1e..dacdfb7692be8fe4f4428c24291b60f6e82ba67b 100644
--- a/frontend/src/metabase/core/hooks/use-form-submit-button/use-form-submit-button.ts
+++ b/frontend/src/metabase/core/hooks/use-form-submit-button/use-form-submit-button.ts
@@ -1,6 +1,8 @@
 import { useEffect, useLayoutEffect, useState } from "react";
 import { useFormikContext } from "formik";
-import useFormState, { FormStatus } from "metabase/core/hooks/use-form-state";
+import useFormContext, {
+  FormStatus,
+} from "metabase/core/hooks/use-form-context";
 
 const STATUS_TIMEOUT = 5000;
 
@@ -17,7 +19,7 @@ const useFormSubmitButton = ({
   isDisabled = false,
 }: UseFormSubmitButtonProps): UseFormSubmitButtonResult => {
   const { isValid, isSubmitting } = useFormikContext();
-  const { status } = useFormState();
+  const { status } = useFormContext();
   const isRecent = useIsRecent(status, STATUS_TIMEOUT);
 
   return {
diff --git a/frontend/src/metabase/core/hooks/use-form-submit/use-form-submit.ts b/frontend/src/metabase/core/hooks/use-form-submit/use-form-submit.ts
index 3d5650f66934de3d1dd2acd6f47aac13dfb46c3d..fd3e9ede5fa45070fd3decf95b3c088378b826e8 100644
--- a/frontend/src/metabase/core/hooks/use-form-submit/use-form-submit.ts
+++ b/frontend/src/metabase/core/hooks/use-form-submit/use-form-submit.ts
@@ -1,5 +1,6 @@
-import { useCallback } from "react";
+import { useCallback, useState } from "react";
 import type { FormikHelpers } from "formik";
+import { FormState } from "metabase/core/context/FormContext";
 import { FormError } from "./types";
 
 export interface UseFormSubmitProps<T> {
@@ -7,30 +8,31 @@ export interface UseFormSubmitProps<T> {
 }
 
 export interface UseFormSubmitResult<T> {
+  state: FormState;
   handleSubmit: (values: T, helpers: FormikHelpers<T>) => void;
 }
 
 const useFormSubmit = <T>({
   onSubmit,
 }: UseFormSubmitProps<T>): UseFormSubmitResult<T> => {
+  const [state, setState] = useState<FormState>({ status: "idle" });
+
   const handleSubmit = useCallback(
     async (data: T, helpers: FormikHelpers<T>) => {
       try {
-        helpers.setStatus({ status: "pending" });
+        setState({ status: "pending" });
         await onSubmit(data, helpers);
-        helpers.setStatus({ status: "fulfilled" });
+        setState({ status: "fulfilled" });
       } catch (error) {
         helpers.setErrors(getFormErrors(error));
-        helpers.setStatus({
-          status: "rejected",
-          message: getFormMessage(error),
-        });
+        setState({ status: "rejected", message: getFormMessage(error) });
       }
     },
     [onSubmit],
   );
 
   return {
+    state,
     handleSubmit,
   };
 };