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) {
...
}
};