The useTyping hook manages typing indicator state for a chat room, automatically tracking users who are currently typing and updating state in realtime.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import { useTyping } from '@ably/chat/react';
const MyComponent = () => {
const { keystroke, stop, currentTypers } = useTyping();
return (
<div>
{currentTypers.length > 0 && (
<p>{currentTypers.map(t => t.clientId).join(', ')} typing...</p>
)}
<input
onInput={() => keystroke()}
onBlur={() => stop()}
/>
</div>
);
};This hook must be used within a ChatRoomProvider.
Parameters
The useTyping hook accepts an optional configuration object:
listeneroptionalTypingListenerReturns
The useTyping hook returns an object with the following properties:
currentTypersTypingMember[]keystrokekeystroke()stopstop()roomStatusRoomStatusroomErrorErrorInfo or UndefinedconnectionStatusConnectionStatusconnectionErrorErrorInfo or UndefinedStart typing
keystroke(): Promise<void>Sends a typing started event to notify other users that the current user is typing.
Events are throttled according to the heartbeatThrottleMs room option to prevent excessive network traffic. If called within the throttle interval, the operation becomes a no-op.
Returns
Promise<void>
Returns a promise. The promise is fulfilled when the typing event has been sent, or rejected with an ErrorInfo object.
Stop typing
stop(): Promise<void>Sends a typing stopped event to notify other users that the current user has stopped typing.
If the user is not currently typing, this operation is a no-op.
Returns
Promise<void>
Returns a promise. The promise is fulfilled when the typing stopped event has been sent, or rejected with an ErrorInfo object.
Example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import { useTyping } from '@ably/chat/react';
import { useState, useCallback } from 'react';
function MessageInput({ onSend }) {
const [text, setText] = useState('');
const { keystroke, stop, currentTypers } = useTyping({
listener: (event) => {
const { change } = event;
if (change.type === 'typing.started') {
console.log(`${change.clientId} started typing`);
}
},
});
const handleInput = useCallback((e) => {
setText(e.target.value);
if (e.target.value.length > 0) {
keystroke();
} else {
stop();
}
}, [keystroke, stop]);
const handleSubmit = useCallback(async () => {
await onSend(text);
setText('');
await stop();
}, [text, onSend, stop]);
return (
<div>
{currentTypers.length > 0 && (
<p>
{currentTypers.length === 1
? `${currentTypers[0].clientId} is typing...`
: `${currentTypers.map(t => t.clientId).join(', ')} are typing...`}
</p>
)}
<input value={text} onChange={handleInput} onBlur={() => stop()} />
<button onClick={handleSubmit}>Send</button>
</div>
);
}