diff --git a/native/markdown/markdown-spoiler.react.js b/native/markdown/markdown-spoiler.react.js
new file mode 100644
--- /dev/null
+++ b/native/markdown/markdown-spoiler.react.js
@@ -0,0 +1,45 @@
+// @flow
+
+import * as React from 'react';
+import { Text } from 'react-native';
+
+import type { ReactElement } from 'lib/shared/markdown';
+
+import { useStyles } from '../themes/colors';
+
+type MarkdownSpoilerProps = {
+  +text: ReactElement,
+  +children?: React.Node,
+};
+
+function MarkdownSpoiler(props: MarkdownSpoilerProps): React.Node {
+  const [isRevealed, setIsRevealed] = React.useState(false);
+  const styles = useStyles(unboundStyles);
+  const { text } = props;
+
+  const onSpoilerClick = React.useCallback(() => {
+    setIsRevealed(true);
+  }, []);
+
+  const memoizedSpoiler = React.useMemo(() => {
+    return (
+      <Text
+        onPress={onSpoilerClick}
+        style={!isRevealed ? styles.spoilerHidden : null}
+      >
+        {text}
+      </Text>
+    );
+  }, [onSpoilerClick, isRevealed, styles.spoilerHidden, text]);
+
+  return memoizedSpoiler;
+}
+
+const unboundStyles = {
+  spoilerHidden: {
+    color: 'spoiler',
+    backgroundColor: 'spoiler',
+  },
+};
+
+export default MarkdownSpoiler;
diff --git a/native/markdown/rules.react.js b/native/markdown/rules.react.js
--- a/native/markdown/rules.react.js
+++ b/native/markdown/rules.react.js
@@ -12,6 +12,7 @@
 
 import { useSelector } from '../redux/redux-utils';
 import MarkdownLink from './markdown-link.react';
+import MarkdownSpoiler from './markdown-spoiler.react';
 import { getMarkdownStyles } from './styles';
 
 export type MarkdownRules = {
@@ -199,9 +200,7 @@
         output: SharedMarkdown.Output<SharedMarkdown.ReactElement>,
         state: SharedMarkdown.State,
       ) => (
-        <Text key={state.key} style={styles.spoiler}>
-          {output(node.content, state)}
-        </Text>
+        <MarkdownSpoiler key={state.key} text={output(node.content, state)} />
       ),
     },
     inlineCode: {