diff --git a/web/modals/search-modal.css b/web/modals/search-modal.css
new file mode 100644
--- /dev/null
+++ b/web/modals/search-modal.css
@@ -0,0 +1,6 @@
+.container {
+  display: flex;
+  flex-direction: column;
+  overflow: hidden;
+  margin: 16px;
+}
diff --git a/web/modals/search-modal.react.js b/web/modals/search-modal.react.js
new file mode 100644
--- /dev/null
+++ b/web/modals/search-modal.react.js
@@ -0,0 +1,38 @@
+// @flow
+
+import * as React from 'react';
+
+import Search from '../components/search.react';
+import Modal from './modal.react';
+import css from './search-modal.css';
+
+type Props = {
+  +name: string,
+  +searchPlaceholder: string,
+  +onClose: () => void,
+  +children: (searchText: string) => React.Node,
+};
+
+function SearchModal(props: Props): React.Node {
+  const [searchText, setSearchText] = React.useState('');
+  const { name, searchPlaceholder, onClose, children } = props;
+  const child = React.useMemo(() => children(searchText), [
+    children,
+    searchText,
+  ]);
+
+  return (
+    <Modal name={name} onClose={onClose}>
+      <div className={css.container}>
+        <Search
+          onChangeText={setSearchText}
+          searchText={searchText}
+          placeholder={searchPlaceholder}
+        />
+        {child}
+      </div>
+    </Modal>
+  );
+}
+
+export default SearchModal;
diff --git a/web/modals/threads/members/members-modal.css b/web/modals/threads/members/members-modal.css
--- a/web/modals/threads/members/members-modal.css
+++ b/web/modals/threads/members/members-modal.css
@@ -1,10 +1,3 @@
-div.membersContainer {
-  display: flex;
-  flex-direction: column;
-  overflow: hidden;
-  margin: 16px;
-}
-
 div.membersList {
   overflow: scroll;
   padding: 8px 0;
diff --git a/web/modals/threads/members/members-modal.react.js b/web/modals/threads/members/members-modal.react.js
--- a/web/modals/threads/members/members-modal.react.js
+++ b/web/modals/threads/members/members-modal.react.js
@@ -7,22 +7,19 @@
 import { memberHasAdminPowers, memberIsAdmin } from 'lib/shared/thread-utils';
 import { type RelativeMemberInfo } from 'lib/types/thread-types';
 
-import Search from '../../../components/search.react';
 import Tabs from '../../../components/tabs.react';
 import { useSelector } from '../../../redux/redux-utils';
-import Modal from '../../modal.react';
+import SearchModal from '../../search-modal.react';
 import ThreadMembersList from './members-list.react';
-import css from './members-modal.css';
 
-type Props = {
+type ContentProps = {
+  +searchText: string,
   +threadID: string,
-  +onClose: () => void,
 };
-function ThreadMembersModal(props: Props): React.Node {
-  const { threadID, onClose } = props;
+function ThreadMembersModalContent(props: ContentProps): React.Node {
+  const { threadID, searchText } = props;
 
   const [tab, setTab] = React.useState<'All Members' | 'Admins'>('All Members');
-  const [searchText, setSearchText] = React.useState('');
 
   const threadInfo = useSelector(state => threadInfoSelector(state)[threadID]);
   const { members: threadMembersNotFiltered } = threadInfo;
@@ -72,19 +69,33 @@
   );
 
   return (
-    <Modal name="Members" onClose={onClose}>
-      <div className={css.membersContainer}>
-        <Search
-          onChangeText={setSearchText}
-          searchText={searchText}
-          placeholder="Search members"
-        />
-        <Tabs.Container activeTab={tab} setTab={setTab}>
-          {allUsersTab}
-          {allAdminsTab}
-        </Tabs.Container>
-      </div>
-    </Modal>
+    <Tabs.Container activeTab={tab} setTab={setTab}>
+      {allUsersTab}
+      {allAdminsTab}
+    </Tabs.Container>
+  );
+}
+
+type Props = {
+  +threadID: string,
+  +onClose: () => void,
+};
+function ThreadMembersModal(props: Props): React.Node {
+  const { onClose, threadID } = props;
+  const renderModalContent = React.useCallback(
+    (searchText: string) => (
+      <ThreadMembersModalContent threadID={threadID} searchText={searchText} />
+    ),
+    [threadID],
+  );
+  return (
+    <SearchModal
+      name="Members"
+      searchPlaceholder="Search members"
+      onClose={onClose}
+    >
+      {renderModalContent}
+    </SearchModal>
   );
 }