我有一个文本区域,我想在用户输入文本时立即更新文本区域文本,但出于明显的效率原因,我不喜欢在每次击键后点击 api。
我尝试使用去抖功能,但每次击键后该功能都会被触发多次,但我在
debounce
中添加了一些延迟
codesandbox link
export default function App() {
const [text, setText] = useState("");
function callAPI(value: string) {
console.log(value);
// CALL API HERE
}
const debouncedAPI = _.debounce(callAPI, 2000);
function onChangeText(e) {
const value = e.target.value;
console.log(`value inside onChangeText: ${value}`);
setText(value);
}
return (
<div className="App">
<textarea
name="textarea"
id=""
value={text}
onChange={(e) => {
onChangeText(e); // Update the state
debouncedAPI(e.target.value); // Call the debounced API with the latest value
}}
></textarea>
</div>
);
}
发生这种情况是因为您在
debouncedAPI
函数中调用了 onChange
函数。这意味着,您可以在每次更改后调用它。要解决此问题,您需要更改防抖机制,该机制会延迟 API 调用,直到用户在指定的时间内停止键入。下面是一个使用自定义 useDebounce
钩子来有效处理去抖逻辑的示例:
export function useDebounce(value, delay = 500): T {
const [debouncedValue, setDebouncedValue] = useState<T>(value);
useEffect(() => {
// Create a timeout to update the debounced value after the specified delay
const timer = setTimeout(() => {
setDebouncedValue(value);
}, delay);
// Cleanup function to clear the timeout if value changes before delay period
return () => {
clearTimeout(timer);
};
}, [value, delay]); // Only re-run effect if value or delay changes
return debouncedValue;
}
useDebounce
钩子旨在将值的更新延迟指定时间段(delay
)以减少操作(例如API请求或事件触发)的频率。它“消除”对 value
的快速更改,确保仅在用户在给定的延迟时间内停止交互后才会发生更新。
export function DebouncedInput() {
const [inputValue, setInputValue] = useState('');
const debouncedValue = useDebounce(inputValue, 500);
useEffect(() => {
if (debouncedValue) {
// Call your API with the debounced value
console.log('API call with value:', debouncedValue);
}
}, [debouncedValue]);
const handleChange = (event) => {
setInputValue(event.target.value);
};
return (
<div>
<input
type="text"
value={inputValue}
onChange={handleChange}
placeholder="search"
/>
</div>
);
}
现在提供了一个输入(或文本区域),用户可以在其中自由键入,但不是在每次击键时触发操作(如 API 调用),而是在用户停止键入后等待指定的延迟,然后再进行 API 调用。