diff --git a/web/modals/threads/thread-settings-delete-tab.react.js b/web/modals/threads/thread-settings-delete-tab.react.js
--- a/web/modals/threads/thread-settings-delete-tab.react.js
+++ b/web/modals/threads/thread-settings-delete-tab.react.js
@@ -2,18 +2,79 @@
 
 import * as React from 'react';
 
+import {
+  deleteThreadActionTypes,
+  deleteThread,
+} from 'lib/actions/thread-actions';
+import { type SetState } from 'lib/types/hook-types.js';
+import { type ThreadInfo } from 'lib/types/thread-types';
+import {
+  useDispatchActionPromise,
+  useServerCall,
+} from 'lib/utils/action-utils';
+
+import Button from '../../components/button.react.js';
+import { useModalContext } from '../modal-provider.react.js';
 import css from './thread-settings-modal.css';
 
 type ThreadSettingsDeleteTabProps = {
   +accountPassword: string,
+  +setAccountPassword: SetState<string>,
   +onChangeAccountPassword: (event: SyntheticEvent<HTMLInputElement>) => void,
   +inputDisabled: boolean,
+  +threadInfo: ThreadInfo,
+  +setErrorMessage: SetState<string>,
 };
 
 function ThreadSettingsDeleteTab(
   props: ThreadSettingsDeleteTabProps,
 ): React.Node {
-  const { accountPassword, onChangeAccountPassword, inputDisabled } = props;
+  const {
+    accountPassword,
+    setAccountPassword,
+    onChangeAccountPassword,
+    inputDisabled,
+    threadInfo,
+    setErrorMessage,
+  } = props;
+
+  const modalContext = useModalContext();
+  const dispatchActionPromise = useDispatchActionPromise();
+  const callDeleteThread = useServerCall(deleteThread);
+
+  const deleteThreadAction = React.useCallback(async () => {
+    try {
+      const response = await callDeleteThread(threadInfo.id, accountPassword);
+      modalContext.popModal();
+      return response;
+    } catch (e) {
+      setErrorMessage(
+        e.message === 'invalid_credentials'
+          ? 'wrong password'
+          : 'unknown error',
+      );
+      setAccountPassword('');
+      // TODO: accountPasswordInput.focus()
+      // (once ref is moved up to functional component)
+      throw e;
+    }
+  }, [
+    accountPassword,
+    callDeleteThread,
+    modalContext,
+    setAccountPassword,
+    setErrorMessage,
+    threadInfo.id,
+  ]);
+
+  const onDelete = React.useCallback(
+    (event: SyntheticEvent<HTMLElement>) => {
+      event.preventDefault();
+      dispatchActionPromise(deleteThreadActionTypes, deleteThreadAction());
+    },
+    [deleteThreadAction, dispatchActionPromise],
+  );
+
   return (
     <>
       <div>
@@ -37,6 +98,9 @@
           />
         </div>
       </div>
+      <Button onClick={onDelete} variant="danger" disabled={inputDisabled}>
+        Delete
+      </Button>
     </>
   );
 }
diff --git a/web/modals/threads/thread-settings-modal.react.js b/web/modals/threads/thread-settings-modal.react.js
--- a/web/modals/threads/thread-settings-modal.react.js
+++ b/web/modals/threads/thread-settings-modal.react.js
@@ -6,7 +6,6 @@
 
 import {
   deleteThreadActionTypes,
-  deleteThread,
   changeThreadSettingsActionTypes,
   changeThreadSettings,
 } from 'lib/actions/thread-actions';
@@ -81,7 +80,6 @@
       state => state.currentUserInfo && state.currentUserInfo.id,
     );
     const userInfos = useSelector(state => state.userStore.userInfos);
-    const callDeleteThread = useServerCall(deleteThread);
     const callChangeThreadSettings = useServerCall(changeThreadSettings);
     const dispatchActionPromise = useDispatchActionPromise();
     const threadInfo: ?ThreadInfo = useSelector(
@@ -136,33 +134,6 @@
       [],
     );
 
-    const deleteThreadAction = React.useCallback(async () => {
-      invariant(threadInfo, 'threadInfo should exist in deleteThreadAction');
-      try {
-        const response = await callDeleteThread(threadInfo.id, accountPassword);
-        modalContext.popModal();
-        return response;
-      } catch (e) {
-        setErrorMessage(
-          e.message === 'invalid_credentials'
-            ? 'wrong password'
-            : 'unknown error',
-        );
-        setAccountPassword('');
-        // TODO: accountPasswordInput.focus()
-        // (once ref is moved up to functional component)
-        throw e;
-      }
-    }, [accountPassword, callDeleteThread, modalContext, threadInfo]);
-
-    const onDelete = React.useCallback(
-      (event: SyntheticEvent<HTMLElement>) => {
-        event.preventDefault();
-        dispatchActionPromise(deleteThreadActionTypes, deleteThreadAction());
-      },
-      [deleteThreadAction, dispatchActionPromise],
-    );
-
     const changeThreadSettingsAction = React.useCallback(async () => {
       invariant(
         threadInfo,
@@ -242,20 +213,17 @@
       mainContent = (
         <ThreadSettingsDeleteTab
           accountPassword={accountPassword}
+          setAccountPassword={setAccountPassword}
           onChangeAccountPassword={onChangeAccountPassword}
           inputDisabled={inputDisabled}
+          threadInfo={threadInfo}
+          setErrorMessage={setErrorMessage}
         />
       );
     }
 
     let buttons;
-    if (currentTabType === 'delete') {
-      buttons = (
-        <Button onClick={onDelete} variant="danger" disabled={inputDisabled}>
-          Delete
-        </Button>
-      );
-    } else {
+    if (currentTabType !== 'delete') {
       buttons = (
         <Button
           type="submit"