diff --git a/frontend/src/metabase/collections/containers/CollectionCreate.jsx b/frontend/src/metabase/collections/containers/CollectionCreate.jsx
deleted file mode 100644
index 923db528236668f8b96b9d4301bbba26788d6421..0000000000000000000000000000000000000000
--- a/frontend/src/metabase/collections/containers/CollectionCreate.jsx
+++ /dev/null
@@ -1,63 +0,0 @@
-/* eslint-disable react/prop-types */
-import React, { Component } from "react";
-import { connect } from "react-redux";
-import { getValues } from "redux-form";
-import { withRouter } from "react-router";
-import { goBack } from "react-router-redux";
-import _ from "underscore";
-
-import Collection from "metabase/entities/collections";
-import { PLUGIN_COLLECTIONS } from "metabase/plugins";
-
-const { REGULAR_COLLECTION } = PLUGIN_COLLECTIONS;
-
-const FORM_NAME = "create-collection";
-
-const mapStateToProps = (state, props) => {
-  const formValues = getValues(state.form[FORM_NAME]);
-  return {
-    form: Collection.selectors.getForm(state, { ...props, formValues }),
-    initialCollectionId: Collection.selectors.getInitialCollectionId(
-      state,
-      props,
-    ),
-  };
-};
-
-const mapDispatchToProps = {
-  goBack,
-};
-
-class CollectionCreate extends Component {
-  handleClose = () => {
-    const { goBack, onClose } = this.props;
-    return onClose ? onClose() : goBack();
-  };
-
-  handleSaved = collection => {
-    const { goBack, onSaved } = this.props;
-    return onSaved ? onSaved(collection) : goBack();
-  };
-
-  render() {
-    const { form, initialCollectionId } = this.props;
-    return (
-      <Collection.ModalForm
-        overwriteOnInitialValuesChange
-        formName={FORM_NAME}
-        form={form}
-        collection={{
-          parent_id: initialCollectionId,
-          authority_level: REGULAR_COLLECTION.type,
-        }}
-        onSaved={this.handleSaved}
-        onClose={this.handleClose}
-      />
-    );
-  }
-}
-
-export default _.compose(
-  withRouter,
-  connect(mapStateToProps, mapDispatchToProps),
-)(CollectionCreate);
diff --git a/frontend/src/metabase/collections/containers/CollectionCreate/CollectionCreate.tsx b/frontend/src/metabase/collections/containers/CollectionCreate/CollectionCreate.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..74ffefec49f6b3a32b029f254c667ef6b24a6aab
--- /dev/null
+++ b/frontend/src/metabase/collections/containers/CollectionCreate/CollectionCreate.tsx
@@ -0,0 +1,104 @@
+import React, { useCallback, useEffect, useState } from "react";
+import { connect } from "react-redux";
+import { withRouter } from "react-router";
+import { goBack } from "react-router-redux";
+import _ from "underscore";
+
+import { Collection as BaseCollection, CollectionId } from "metabase-types/api";
+import { State } from "metabase-types/store";
+
+import Collections from "metabase/entities/collections";
+
+import CollectionCreateForm from "./CollectionCreateForm";
+
+type Collection = BaseCollection & {
+  parent_id: CollectionId;
+};
+
+interface CollectionCreateOwnProps {
+  goBack?: () => void;
+  onClose?: () => void;
+  onSaved?: (collection: Collection) => void;
+}
+
+interface CollectionCreateStateProps {
+  initialCollectionId: CollectionId;
+}
+
+interface CollectionCreateProps
+  extends CollectionCreateOwnProps,
+    CollectionCreateStateProps {}
+
+function mapStateToProps(state: State, props: CollectionCreateOwnProps) {
+  return {
+    initialCollectionId: Collections.selectors.getInitialCollectionId(
+      state,
+      props,
+    ),
+  };
+}
+
+const mapDispatchToProps = {
+  goBack,
+};
+
+function CollectionCreate({
+  initialCollectionId,
+  goBack,
+  onClose,
+  onSaved,
+}: CollectionCreateProps) {
+  const [parentCollectionId, setParentCollectionId] = useState<CollectionId>(
+    initialCollectionId,
+  );
+  const [hasSetParentCollection, setHasSetParentCollection] = useState(false);
+
+  useEffect(() => {
+    if (!hasSetParentCollection) {
+      setParentCollectionId(initialCollectionId);
+    }
+  }, [initialCollectionId, hasSetParentCollection]);
+
+  const onChangeValues = useCallback(
+    (collection: Collection) => {
+      if (collection.parent_id !== parentCollectionId) {
+        setParentCollectionId(collection.parent_id);
+        setHasSetParentCollection(true);
+      }
+    },
+    [parentCollectionId],
+  );
+
+  const handleClose = useCallback(() => {
+    if (onClose) {
+      onClose();
+    } else {
+      goBack?.();
+    }
+  }, [goBack, onClose]);
+
+  const handleSave = useCallback(
+    (collection: Collection) => {
+      if (onSaved) {
+        onSaved(collection);
+      } else {
+        goBack?.();
+      }
+    },
+    [goBack, onSaved],
+  );
+
+  return (
+    <CollectionCreateForm
+      parentCollectionId={parentCollectionId}
+      onChange={onChangeValues}
+      onSaved={handleSave}
+      onClose={handleClose}
+    />
+  );
+}
+
+export default _.compose(
+  withRouter,
+  connect(mapStateToProps, mapDispatchToProps),
+)(CollectionCreate);
diff --git a/frontend/src/metabase/collections/containers/CollectionCreate/CollectionCreateForm.tsx b/frontend/src/metabase/collections/containers/CollectionCreate/CollectionCreateForm.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..ca7e29e0452195cb23db0de0d1ccaf949ddd9874
--- /dev/null
+++ b/frontend/src/metabase/collections/containers/CollectionCreate/CollectionCreateForm.tsx
@@ -0,0 +1,64 @@
+import React from "react";
+import { connect } from "react-redux";
+import { withRouter } from "react-router";
+import _ from "underscore";
+
+import { Collection as BaseCollection, CollectionId } from "metabase-types/api";
+import { State } from "metabase-types/store";
+
+import Collections from "metabase/entities/collections";
+import { PLUGIN_COLLECTIONS } from "metabase/plugins";
+
+const { REGULAR_COLLECTION } = PLUGIN_COLLECTIONS;
+
+type Collection = BaseCollection & {
+  parent_id: CollectionId;
+};
+
+interface CollectionCreateFormOwnProps {
+  parentCollectionId: CollectionId;
+  onChange: (collection: Collection) => void;
+  onSaved?: (collection: Collection) => void;
+  onClose?: () => void;
+}
+
+interface CollectionCreateFormStateProps {
+  form: unknown;
+}
+
+interface CollectionCreateFormProps
+  extends CollectionCreateFormOwnProps,
+    CollectionCreateFormStateProps {}
+
+function mapStateToProps(state: State, props: CollectionCreateFormOwnProps) {
+  return {
+    form: Collections.selectors.getForm(state, props),
+  };
+}
+
+function CollectionCreateForm({
+  form,
+  parentCollectionId,
+  onChange,
+  onSaved,
+  onClose,
+}: CollectionCreateFormProps) {
+  return (
+    <Collections.ModalForm
+      form={form}
+      collection={{
+        parent_id: parentCollectionId,
+        authority_level: REGULAR_COLLECTION.type,
+      }}
+      overwriteOnInitialValuesChange
+      onChange={onChange}
+      onSaved={onSaved}
+      onClose={onClose}
+    />
+  );
+}
+
+export default _.compose(
+  withRouter,
+  connect(mapStateToProps),
+)(CollectionCreateForm);
diff --git a/frontend/src/metabase/collections/containers/CollectionCreate/index.ts b/frontend/src/metabase/collections/containers/CollectionCreate/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..eba57ce7ecb86e71f38bc48d875a3745393b6968
--- /dev/null
+++ b/frontend/src/metabase/collections/containers/CollectionCreate/index.ts
@@ -0,0 +1 @@
+export { default } from "./CollectionCreate";
diff --git a/frontend/src/metabase/collections/containers/CollectionEdit.jsx b/frontend/src/metabase/collections/containers/CollectionEdit.jsx
deleted file mode 100644
index a70970b92dfe84248fe782a5013f99a51af2e6f5..0000000000000000000000000000000000000000
--- a/frontend/src/metabase/collections/containers/CollectionEdit.jsx
+++ /dev/null
@@ -1,56 +0,0 @@
-/* eslint-disable react/prop-types */
-import React, { Component } from "react";
-
-import { connect } from "react-redux";
-import { goBack, push } from "react-router-redux";
-
-import * as Urls from "metabase/lib/urls";
-import Collection from "metabase/entities/collections";
-
-function mapStateToProps(state, props) {
-  return {
-    form: Collection.selectors.getForm(state, props),
-  };
-}
-
-function CollectionForm({ form, collection, onSave, onClose }) {
-  return (
-    <Collection.ModalForm
-      form={form}
-      collection={collection}
-      onSaved={onSave}
-      onClose={onClose}
-    />
-  );
-}
-
-const UpdateCollectionForm = connect(mapStateToProps)(CollectionForm);
-
-const mapDispatchToProps = {
-  push,
-  goBack,
-};
-
-class CollectionEdit extends Component {
-  onSave = updatedCollection => {
-    const url = Urls.collection(updatedCollection);
-    this.props.push(url);
-  };
-
-  render() {
-    const collectionId = Urls.extractCollectionId(this.props.params.slug);
-    return (
-      <Collection.Loader id={collectionId}>
-        {({ collection, update }) => (
-          <UpdateCollectionForm
-            collection={collection}
-            onSave={this.onSave}
-            onClose={this.props.goBack}
-          />
-        )}
-      </Collection.Loader>
-    );
-  }
-}
-
-export default connect(null, mapDispatchToProps)(CollectionEdit);
diff --git a/frontend/src/metabase/collections/containers/CollectionEdit/CollectionEdit.tsx b/frontend/src/metabase/collections/containers/CollectionEdit/CollectionEdit.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..f2cf96dc4eeabe32b4f48e4ec5d1547d43454270
--- /dev/null
+++ b/frontend/src/metabase/collections/containers/CollectionEdit/CollectionEdit.tsx
@@ -0,0 +1,92 @@
+import React, { useCallback, useEffect, useState } from "react";
+import { connect } from "react-redux";
+import { goBack, push, LocationAction } from "react-router-redux";
+import _ from "underscore";
+
+import * as Urls from "metabase/lib/urls";
+import Collections from "metabase/entities/collections";
+
+import { Collection as BaseCollection, CollectionId } from "metabase-types/api";
+import { State } from "metabase-types/store";
+
+import CollectionEditForm from "./CollectionEditForm";
+
+type Collection = BaseCollection & {
+  parent_id: CollectionId;
+};
+
+interface CollectionEditOwnProps {
+  params: {
+    slug: string;
+  };
+}
+
+interface CollectionEditLoaderProps {
+  collection: Collection;
+}
+
+interface CollectionEditDispatchProps {
+  push: LocationAction;
+  goBack: () => void;
+}
+
+interface CollectionEditProps
+  extends CollectionEditOwnProps,
+    CollectionEditLoaderProps,
+    CollectionEditDispatchProps {}
+
+const mapDispatchToProps = {
+  push,
+  goBack,
+};
+
+function CollectionEdit({ collection, push, goBack }: CollectionEditProps) {
+  const [parentCollectionId, setParentCollectionId] = useState<CollectionId>(
+    collection?.parent_id,
+  );
+  const [hasSetParentCollection, setHasSetParentCollection] = useState(false);
+
+  useEffect(() => {
+    if (collection && !hasSetParentCollection) {
+      setParentCollectionId(collection.parent_id);
+    }
+  }, [collection, hasSetParentCollection]);
+
+  const onChangeValues = useCallback(
+    (collection: Collection) => {
+      if (collection.parent_id !== parentCollectionId) {
+        setParentCollectionId(collection.parent_id);
+        setHasSetParentCollection(true);
+      }
+    },
+    [parentCollectionId],
+  );
+
+  const onSave = useCallback(
+    collection => {
+      push(Urls.collection(collection));
+    },
+    [push],
+  );
+
+  return (
+    <CollectionEditForm
+      collection={collection}
+      parentCollectionId={parentCollectionId}
+      onChange={onChangeValues}
+      onSave={onSave}
+      onClose={goBack}
+    />
+  );
+}
+
+export default _.compose(
+  connect<unknown, CollectionEditDispatchProps, CollectionEditOwnProps, State>(
+    null,
+    mapDispatchToProps,
+  ),
+  Collections.load({
+    id: (state: State, props: CollectionEditOwnProps) =>
+      Urls.extractCollectionId(props.params.slug),
+  }),
+)(CollectionEdit);
diff --git a/frontend/src/metabase/collections/containers/CollectionEdit/CollectionEditForm.tsx b/frontend/src/metabase/collections/containers/CollectionEdit/CollectionEditForm.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..21a60833c7004ca4e3e7700488c3a6e50fa796bb
--- /dev/null
+++ b/frontend/src/metabase/collections/containers/CollectionEdit/CollectionEditForm.tsx
@@ -0,0 +1,54 @@
+import React from "react";
+import { connect } from "react-redux";
+
+import Collections from "metabase/entities/collections";
+
+import { Collection as BaseCollection, CollectionId } from "metabase-types/api";
+import { State } from "metabase-types/store";
+
+type Collection = BaseCollection & {
+  parent_id: CollectionId;
+};
+
+interface CollectionEditFormOwnProps {
+  collection: Collection;
+  parentCollectionId: CollectionId;
+  onChange: (collection: Collection) => void;
+  onSave: (collection: Collection) => void;
+  onClose: () => void;
+}
+
+interface CollectionEditFormStateProps {
+  form: unknown;
+}
+
+interface CollectionEditProps
+  extends CollectionEditFormOwnProps,
+    CollectionEditFormStateProps {}
+
+function mapStateToProps(state: State, props: CollectionEditFormOwnProps) {
+  return {
+    form: Collections.selectors.getForm(state, props),
+  };
+}
+
+function CollectionEditForm({
+  form,
+  collection,
+  onChange,
+  onSave,
+  onClose,
+}: CollectionEditProps) {
+  return (
+    <Collections.ModalForm
+      form={form}
+      collection={collection}
+      overwriteOnInitialValuesChange
+      onChange={onChange}
+      onSaved={onSave}
+      onClose={onClose}
+    />
+  );
+}
+
+export default connect(mapStateToProps)(CollectionEditForm);
diff --git a/frontend/src/metabase/collections/containers/CollectionEdit/index.ts b/frontend/src/metabase/collections/containers/CollectionEdit/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b7bebb0cfa42438adde4aa186740902222be8903
--- /dev/null
+++ b/frontend/src/metabase/collections/containers/CollectionEdit/index.ts
@@ -0,0 +1 @@
+export { default } from "./CollectionEdit";
diff --git a/frontend/src/metabase/containers/Form.jsx b/frontend/src/metabase/containers/Form.jsx
index ad9960a08bbc5525500b3917c4e8539d5fb7f1d6..63d7e69bd15f56c776d77bc0d2e19905e1a9593f 100644
--- a/frontend/src/metabase/containers/Form.jsx
+++ b/frontend/src/metabase/containers/Form.jsx
@@ -169,6 +169,7 @@ class Form extends React.Component {
         initialize(this.props.formName, this._getInitialValues(), newFields),
       );
     }
+    this.props.onChange?.(this.props.values);
   }
 
   _registerFormField = field => {
diff --git a/frontend/src/metabase/entities/collections/forms.js b/frontend/src/metabase/entities/collections/forms.js
index 9a440e8dba9ebcb4682883a1eb76441381531d12..f8d68ccbc47bc5f4b66255983d8791069cba5709 100644
--- a/frontend/src/metabase/entities/collections/forms.js
+++ b/frontend/src/metabase/entities/collections/forms.js
@@ -63,19 +63,15 @@ function isPersonalOrPersonalChild(collection, collectionList) {
 export const getFormSelector = createSelector(
   [
     (state, props) => props.collection || {},
-    (state, props) => props.formValues || {},
+    (state, props) => props.parentCollectionId,
     state => state.entities.collections || {},
     getUser,
   ],
-  (collection, formValues, allCollections, user) => {
+  (collection, parentCollectionId, allCollections, user) => {
     const collectionList = Object.values(allCollections);
     const extraFields = [];
 
-    const creatingNewCollection = !collection.id;
-    const parentId = creatingNewCollection
-      ? formValues.parent_id
-      : collection.parent_id;
-
+    const parentId = parentCollectionId || collection?.parent_id;
     const parentCollection = allCollections[parentId];
     const canManageAuthorityLevel =
       user.is_superuser &&