Tengo un componente tan funcional. Cuando un usuario ingresa una entrada, envío un mensaje al servidor y envío a otros usuarios lo que alguien escribe. Aquí está el código:
const ChatInput = (props) => { const [message, setMessage] = useState(''); const typingMessage = () =>{ socket.emit('typing',props.username); } return ( <div className> <Input value = {message} onChange = { (e) => typingMessage(e.target.value) } placeholder="Type a message here" /> <Button onClick={sendMessage} icon={<SendOutlined /> }/> </div> ); };¿Cómo hago un seguimiento de que el usuario ha dejado de escribir? ¿Si no ingresa nada en la entrada durante más de 10 segundos?
Necesita la función de rebote, que contará 10 segundos (puede ser un tiempo diferente, depende de usted) después de la última entrada (disparador onChange)
function debounce(func, timeout = 10000){ let timer; return (...args) => { clearTimeout(timer); timer = setTimeout(() => { func.apply(this, args); }, timeout); }; } function saveInput(){ console.log('User has stopped writting 10 sec ago'); } const processChange = debounce(() => saveInput()); const typingMessage = () =>{ socket.emit('typing',props.username); processChange() }Puede usar una combinación de onFocus , onBlur y onMouseLeave , de tal manera que cuando ocurre onFocus , él está escribiendo, cuando ocurre onBlur , ya no está escribiendo, y cuando ocurre onMouseLeave o cuando hace clic en enviar, usted onBlur tú mismo. Como abajo:
Supuse que su componente de
Inputpuede reenviarref. Si no, hazlo siguiendo las referencias de reenvío .
const ChatInput = (props) => { const [message, setMessage] = useState(""); const inputRef = useRef(); const typingMessage = () => { socket.emit("typing", props.username); }; const notTypingMessage = () => { socket.emit("typing", ""); }; return ( <div className> <Input ref={inputRef} value={message} onChange={(e) => setMessage(e.target.value)} onFocus={() => typingMessage()} onBlur={() => notTypingMessage()} onMouseLeave={() => inputRef?.current.blur()} placeholder="Type a message here" /> <Button onClick={()=>{sendMessage(); inputRef?.current.blur()}} icon={<SendOutlined />} /> </div> ); }; export default ChatInput;stoppedTyping evento de escritura detenida. const emit = (action, data) => { console.log(action, data) } function App() { const props = { username: 'me' } const [message, setMessage] = useState(''); const [isTyping, setIsTyping] = useState(false); useEffect(() => { if (message && !isTyping) { emit('stoppedTyping', props.username) } }, [isTyping]) const typingMessage = (v) => { emit('typing', props.username); setMessage(v) } const sendMessage = (e) => { console.log(e) } return ( <div className=''> <input value={message} onKeyDown={() => !isTyping && setIsTyping(true)} onKeyUp={() => { setTimeout(() => { setIsTyping((t) => t ? false : t) }, 1000) }} onChange={ (e) => typingMessage(e.target.value) } placeholder="Type a message here" /> <button onClick={sendMessage} >send</button> <pre>{ JSON.stringify({ message, isTyping }) }</pre> </div> ); }