React组件setState导致onKeyPress重复打印composing问题求解
问题根源
你当前React代码反复打印composing的核心原因是:executeHandlePress是函数内的普通局部变量,每次调用setMessageInput更新状态触发组件重渲染时,这个变量都会被重置为初始值true,所以每次按键都会跳过判断直接打印composing。你贴的原生JS片段里executeHandlePress是全局变量,不会随页面操作重置,所以能正常运行。
修复后可正常运行的React代码
import { useRef, useState } from 'react'; import ReactDOM from 'react-dom'; const DEBOUNCE_THRESHOLD = 5000; function App() { const [messageInput, setMessageInput] = useState(""); const timeoutHandler = useRef(null); // 用useRef存储标识,重渲染时值不会被重置 const executeHandlePress = useRef(true); const handleChange = () => { if (timeoutHandler.current) { clearTimeout(timeoutHandler.current); } timeoutHandler.current = setTimeout(() => { console.log("paused"); }, DEBOUNCE_THRESHOLD); }; const handleMessagePress = (e) => { if (!executeHandlePress.current) { return; } console.log("composing"); executeHandlePress.current = false; setTimeout(() => { executeHandlePress.current = true; }, DEBOUNCE_THRESHOLD); }; const handleMessageChange = (message) => { setMessageInput(message); }; const handleMessagePress1 = (e) => { if (e.key === "Enter" || e === "send") { console.log("sendMessage"); } }; return ( <> <input value={messageInput} type="text" id="messageInputField" placeholder="Write your message..." onKeyPress={(e) => { handleMessagePress(e); handleMessagePress1(e); }} onChange={(e) => { handleMessageChange(e.target.value); handleChange(); }} /> </> ); } ReactDOM.render(<App />, document.body);
逻辑说明
- 按键触发逻辑:用户按下按键时,只有
executeHandlePress为true才会打印composing,打印后立刻将标识设为false,同时启动5秒定时器重置标识,确保5秒内连续输入不会重复打印 - 输入停止判断逻辑:每次输入内容变化时清空上一次的停止定时器,重新计时5秒,5秒内没有新输入就打印
paused,符合防抖判断逻辑
内容的提问来源于stack exchange,提问作者Puneet Biswas
相关产品推荐
相关产品推荐

