diff --git a/lib/shared/community-utils.js b/lib/shared/community-utils.js
--- a/lib/shared/community-utils.js
+++ b/lib/shared/community-utils.js
@@ -1,7 +1,68 @@
 // @flow
 
+import * as React from 'react';
+
+import {
+  deleteFarcasterChannelTagActionTypes,
+  useDeleteFarcasterChannelTag,
+} from '../actions/community-actions.js';
+import { createLoadingStatusSelector } from '../selectors/loading-selectors.js';
+import type { SetState } from '../types/hook-types.js';
+import { useDispatchActionPromise } from '../utils/redux-promise-utils.js';
+import { useSelector } from '../utils/redux-utils.js';
+
 function farcasterChannelTagBlobHash(farcasterChannelID: string): string {
   return `farcaster_channel_tag_${farcasterChannelID}`;
 }
 
-export { farcasterChannelTagBlobHash };
+const deleteFarcasterChannelTagStatusSelector = createLoadingStatusSelector(
+  deleteFarcasterChannelTagActionTypes,
+);
+function useRemoveFarcasterChannelTag(
+  commCommunityID: string,
+  farcasterChannelID: string,
+  setError: SetState<?string>,
+): {
+  +removeTag: () => mixed,
+  +isLoading: boolean,
+} {
+  const dispatchActionPromise = useDispatchActionPromise();
+
+  const deleteFarcasterChannelTag = useDeleteFarcasterChannelTag();
+
+  const createDeleteActionPromise = React.useCallback(async () => {
+    try {
+      return await deleteFarcasterChannelTag({
+        commCommunityID,
+        farcasterChannelID,
+      });
+    } catch (e) {
+      setError(e.message);
+      throw e;
+    }
+  }, [
+    commCommunityID,
+    deleteFarcasterChannelTag,
+    farcasterChannelID,
+    setError,
+  ]);
+
+  const removeTag = React.useCallback(() => {
+    void dispatchActionPromise(
+      deleteFarcasterChannelTagActionTypes,
+      createDeleteActionPromise(),
+    );
+  }, [createDeleteActionPromise, dispatchActionPromise]);
+
+  const deleteFarcasterChannelTagStatus = useSelector(
+    deleteFarcasterChannelTagStatusSelector,
+  );
+  const isLoading = deleteFarcasterChannelTagStatus === 'loading';
+
+  return {
+    removeTag,
+    isLoading,
+  };
+}
+
+export { farcasterChannelTagBlobHash, useRemoveFarcasterChannelTag };
diff --git a/native/community-settings/tag-farcaster-channel/remove-tag-button.react.js b/native/community-settings/tag-farcaster-channel/remove-tag-button.react.js
--- a/native/community-settings/tag-farcaster-channel/remove-tag-button.react.js
+++ b/native/community-settings/tag-farcaster-channel/remove-tag-button.react.js
@@ -3,22 +3,12 @@
 import * as React from 'react';
 import { Text, ActivityIndicator } from 'react-native';
 
-import {
-  deleteFarcasterChannelTagActionTypes,
-  useDeleteFarcasterChannelTag,
-} from 'lib/actions/community-actions.js';
-import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
+import { useRemoveFarcasterChannelTag } from 'lib/shared/community-utils.js';
 import type { SetState } from 'lib/types/hook-types.js';
-import { useDispatchActionPromise } from 'lib/utils/redux-promise-utils.js';
 
 import Button from '../../components/button.react.js';
-import { useSelector } from '../../redux/redux-utils.js';
 import { useStyles, useColors } from '../../themes/colors.js';
 
-const deleteFarcasterChannelTagStatusSelector = createLoadingStatusSelector(
-  deleteFarcasterChannelTagActionTypes,
-);
-
 type Props = {
   +communityID: string,
   +channelID: string,
@@ -31,56 +21,24 @@
   const styles = useStyles(unboundStyles);
   const colors = useColors();
 
-  const dispatchActionPromise = useDispatchActionPromise();
-
-  const deleteFarcasterChannelTag = useDeleteFarcasterChannelTag();
-
-  const createDeleteActionPromise = React.useCallback(async () => {
-    try {
-      return await deleteFarcasterChannelTag({
-        commCommunityID: communityID,
-        farcasterChannelID: channelID,
-      });
-    } catch (e) {
-      setError(e.message);
-      throw e;
-    }
-  }, [channelID, communityID, deleteFarcasterChannelTag, setError]);
-
-  const onPressRemoveTag = React.useCallback(() => {
-    void dispatchActionPromise(
-      deleteFarcasterChannelTagActionTypes,
-      createDeleteActionPromise(),
-    );
-  }, [createDeleteActionPromise, dispatchActionPromise]);
-
-  const deleteFarcasterChannelTagStatus = useSelector(
-    deleteFarcasterChannelTagStatusSelector,
+  const { removeTag, isLoading } = useRemoveFarcasterChannelTag(
+    communityID,
+    channelID,
+    setError,
   );
 
-  const isLoadingDeleteFarcasterChannelTag =
-    deleteFarcasterChannelTagStatus === 'loading';
-
   const buttonContent = React.useMemo(() => {
-    if (isLoadingDeleteFarcasterChannelTag) {
+    if (isLoading) {
       return (
         <ActivityIndicator size="small" color={colors.panelForegroundLabel} />
       );
     }
 
     return <Text style={styles.buttonText}>Remove tag</Text>;
-  }, [
-    colors.panelForegroundLabel,
-    isLoadingDeleteFarcasterChannelTag,
-    styles.buttonText,
-  ]);
+  }, [colors.panelForegroundLabel, isLoading, styles.buttonText]);
 
   return (
-    <Button
-      style={styles.button}
-      disabled={isLoadingDeleteFarcasterChannelTag}
-      onPress={onPressRemoveTag}
-    >
+    <Button style={styles.button} disabled={isLoading} onPress={removeTag}>
       {buttonContent}
     </Button>
   );