const MyCustomMessageComponent = () => { const { message } = useMessageContext(); const handleDelete = useDeleteHandler(message); if (message.type === "deleted") { return <p>Nothing to see here.</p>; } return ( <div> {message.text} <button onClick={handleDelete}>Delete, please</button> </div> ); };Message Hooks
The Stream Chat React library provides a variety of useful hooks for use in your custom Message component.
Hooks
useActionHandler
A custom hook to handler function to handle when an action is sent in a Channel.
useDeleteHandler
A custom hook to handle message deletion.
useEditHandler
A custom hook to handle message editing. Returns an object with an editing state boolean and handlers for setting and clearing edit mode.
const MyCustomMessageComponent = () => { const { message } = useMessageContext(); const { editing, setEdit, clearEdit } = useEditHandler(); if (editing) { return ( <div> Editing: {message.text} <button onClick={clearEdit}>Cancel</button> </div> ); } return ( <div> {message.text} <button onClick={setEdit}>Edit</button> </div> ); };useFlagHandler
A custom hook to handle flagging messages. Returns an event handler that processes message flagging.
const MyCustomMessageComponent = () => { const { message } = useMessageContext(); const { addNotification } = useChannelActionContext(); const handleFlagging = useFlagHandler(message, { notify: addNotification }); return ( <div> {message.text} <button onClick={handleFlagging}>Flag this message</button> </div> ); };useMentionsHandler
A custom hook to give you access to message mentions and returns handlers for mentions click and hover events.
const MyCustomMessageComponent = () => { const { message } = useMessageContext(); const { onMentionsClick, onMentionsHover } = useMentionsHandler(message); return ( <div onClick={onMentionsClick} onHover={onMentionsHover}> {message.text} </div> ); };useMuteHandler
A custom hook to handle muting users. Returns an event handler that processes user muting.
const MyCustomMessageComponent = () => { const { message } = useMessageContext(); const { addNotification } = useChannelActionContext(); const handleMute = useMuteHandler(message, { notify: addNotification }); return ( <div> {message.text} <button onClick={handleMute}>Mute the user that sent this!</button> </div> ); };useOpenThreadHandler
A custom hook to handle the opening of a thread in the current channel. Returns an event handler to open a thread.
const MyCustomMessageComponent = () => { const { message } = useMessageContext(); const onThreadClick = useOpenThreadHandler(message); return ( <div> {message.text} <button onClick={onThreadClick}>Reply</button> </div> ); };usePinHandler
A custom hook to handle message pinning. It provides the permission status of the connected user and a function to toggle pinned status of of a message.
const MyCustomMessageComponent = () => { const { message, pinPermissions } = useMessageContext(); const { addNotification } = useChannelActionContext(); const { canPin, handlePin } = usePinHandler(message, pinPermissions, { notify: addNotification }); const handleClick = () => { if (canPin) handlePin(message); } return ( <div className={message.pinned ? 'pinned' : ''} onClick={handleClick}> <p>{message.text}</p> </div> ); }; />useReactionHandler
A custom hook to handle message reactions.
const MyCustomMessageComponent = () => { const { message } = useMessageContext(); const onReactionClick = useReactionHandler(message); return ( <div> {message.text} <button onClick={(e) => onReactionClick("nice", e)}>Nice!</button> <button onClick={(e) => onReactionClick("not-nice", e)}> I don't like it! </button> </div> ); };useReactionsFetcher
A custom hook to handle loading message reactions. Returns an async function that loads and returns message reactions.
import { useQuery } from "react-query"; const MyCustomReactionsList = () => { const { message } = useMessageContext(); const { addNotification } = useChannelActionContext(); const handleFetchReactions = useReactionsFetcher(message, { notify: addNotification, }); // This example relies on react-query - but you can use you preferred method // of fetching data instead const { data } = useQuery( ["message", message.id, "reactions"], handleFetchReactions, ); if (!data) { return null; } return ( <> {data.map((reaction) => ( <span key={reaction.type}>reaction.type</span> ))} </> ); };This function limits the number of loaded reactions to 1200. To customize this behavior, provide your own loader function instead.
useRetryHandler
A custom hook to handle the retry of sending a message.
const MyCustomMessageComponent = () => { const { message } = useMessageContext(); const retrySend = useRetryHandler(); if (message.status === "failed") { const onRetry = () => retrySend(message); return ( <div> Failed to send: {message.text} <button onClick={onRetry}>Retry</button> </div> ); } return <div>{message.text}</div>; };useUserHandler
A custom hook that exposes the info for a message’s user. Returns event handlers for click and hover events for the user.
const MyCustomMessageComponent = () => { const { message } = useMessageContext(); const { onUserClick, onUserHover } = useUserHandler(message, { onUserClickHandler: (e, user) => console.log(`Message from ${user}`), onUserHoverHandler: (e, user) => console.log(`Message from ${user}`), }); return ( <div onClick={onUserClick} onHover={onUserHover}> {message.text} </div> ); };useUserRole
A custom hook that exposes the info for a user’s role for a certain message. Returns an object with the user’s role information.
const MyCustomMessageComponent = () => { const { message } = useMessageContext(); const { canDelete, canEdit, canFlag, canMute, canQuote, canReact, canReply, isAdmin, isModerator, isMyMessage, isOwner, } = useUserRole(message); if (isMyMessage || isAdmin) { ... } };