diff --git a/web/chat/inline-engagement.css b/web/chat/inline-engagement.css
--- a/web/chat/inline-engagement.css
+++ b/web/chat/inline-engagement.css
@@ -23,8 +23,7 @@
   flex-direction: row-reverse;
 }
 
-a.sidebarContainer,
-a.reactionContainer {
+a.sidebarContainer {
   background: var(--inline-engagement-bg);
   color: var(--inline-engagement-color);
   font-size: var(--s-font-14);
@@ -37,16 +36,10 @@
   gap: 4px;
 }
 
-a.sidebarContainer:hover,
-a.reactionContainer:hover {
+a.sidebarContainer:hover {
   background: var(--inline-engagement-bg-hover);
 }
 
-a.reactionContainerSelected {
-  border: 1px solid var(--inline-engagement-color);
-  padding: 3px 7px;
-}
-
 div.unread {
   font-weight: bold;
 }
diff --git a/web/chat/inline-engagement.react.js b/web/chat/inline-engagement.react.js
--- a/web/chat/inline-engagement.react.js
+++ b/web/chat/inline-engagement.react.js
@@ -6,12 +6,11 @@
 import { useModalContext } from 'lib/components/modal-provider.react.js';
 import type { ReactionInfo } from 'lib/selectors/chat-selectors.js';
 import { getInlineEngagementSidebarText } from 'lib/shared/inline-engagement-utils.js';
-import { useNextLocalID } from 'lib/shared/message-utils.js';
 import type { MessageInfo } from 'lib/types/message-types.js';
 import type { ThreadInfo } from 'lib/types/thread-types.js';
 
 import css from './inline-engagement.css';
-import { useSendReaction } from './reaction-message-utils.js';
+import ReactionPill from './reaction-pill.react.js';
 import CommIcon from '../CommIcon.react.js';
 import { useOnClickThread } from '../selectors/thread-selectors.js';
 
@@ -78,47 +77,21 @@
     );
   }, [sidebarThreadInfo, repliesText, onClickSidebar]);
 
-  const localID = useNextLocalID();
-  const sendReaction = useSendReaction(
-    messageInfo.id,
-    localID,
-    threadInfo.id,
-    reactions,
-  );
-
-  const onClickReaction = React.useCallback(
-    (event: SyntheticEvent<HTMLElement>, reaction: string) => {
-      event.preventDefault();
-      sendReaction(reaction);
-    },
-    [sendReaction],
-  );
-
   const reactionsList = React.useMemo(() => {
     if (Object.keys(reactions).length === 0) {
       return null;
     }
 
-    return Object.keys(reactions).map(reaction => {
-      const reactionInfo = reactions[reaction];
-      const numOfReacts = reactionInfo.users.length;
-
-      const reactionClassName = classNames({
-        [css.reactionContainer]: true,
-        [css.reactionContainerSelected]: reactionInfo.viewerReacted,
-      });
-
-      return (
-        <a
-          onClick={event => onClickReaction(event, reaction)}
-          className={reactionClassName}
-          key={reaction}
-        >
-          {`${reaction} ${numOfReacts}`}
-        </a>
-      );
-    });
-  }, [reactions, onClickReaction]);
+    return Object.keys(reactions).map(reaction => (
+      <ReactionPill
+        key={reaction}
+        reaction={reaction}
+        messageID={messageInfo.id}
+        threadID={threadInfo.id}
+        reactions={reactions}
+      />
+    ));
+  }, [reactions, messageInfo.id, threadInfo.id]);
 
   const containerClasses = classNames([
     css.inlineEngagementContainer,
diff --git a/web/chat/reaction-pill.css b/web/chat/reaction-pill.css
new file mode 100644
--- /dev/null
+++ b/web/chat/reaction-pill.css
@@ -0,0 +1,21 @@
+a.reactionContainer {
+  background: var(--inline-engagement-bg);
+  color: var(--inline-engagement-color);
+  font-size: var(--s-font-14);
+  line-height: var(--line-height-text);
+  transition: background 0.2s ease-in-out;
+  padding: 4px 8px;
+  border-radius: 8px;
+  display: flex;
+  align-items: center;
+  gap: 4px;
+}
+
+a.reactionContainer:hover {
+  background: var(--inline-engagement-bg-hover);
+}
+
+a.reactionContainerSelected {
+  border: 1px solid var(--inline-engagement-color);
+  padding: 3px 7px;
+}
diff --git a/web/chat/reaction-pill.react.js b/web/chat/reaction-pill.react.js
new file mode 100644
--- /dev/null
+++ b/web/chat/reaction-pill.react.js
@@ -0,0 +1,48 @@
+// @flow
+
+import classNames from 'classnames';
+import * as React from 'react';
+
+import type { ReactionInfo } from 'lib/selectors/chat-selectors.js';
+import { useNextLocalID } from 'lib/shared/message-utils.js';
+
+import { useSendReaction } from './reaction-message-utils.js';
+import css from './reaction-pill.css';
+
+type Props = {
+  +reaction: string,
+  +messageID: ?string,
+  +threadID: string,
+  +reactions: ReactionInfo,
+};
+
+function ReactionPill(props: Props): React.Node {
+  const { reaction, messageID, threadID, reactions } = props;
+
+  const localID = useNextLocalID();
+  const sendReaction = useSendReaction(messageID, localID, threadID, reactions);
+
+  const onClickReaction = React.useCallback(
+    (event: SyntheticEvent<HTMLElement>) => {
+      event.preventDefault();
+      sendReaction(reaction);
+    },
+    [reaction, sendReaction],
+  );
+
+  const reactionInfo = reactions[reaction];
+  const numOfReacts = reactionInfo.users.length;
+
+  const reactionClassName = classNames({
+    [css.reactionContainer]: true,
+    [css.reactionContainerSelected]: reactionInfo.viewerReacted,
+  });
+
+  return (
+    <a onClick={onClickReaction} className={reactionClassName} key={reaction}>
+      {`${reaction} ${numOfReacts}`}
+    </a>
+  );
+}
+
+export default ReactionPill;