如何即时设置文本区域的值并在2秒后调用api以提高效率

问题描述 投票:0回答:1

我有一个文本区域,我想在用户输入文本时立即更新文本区域文本,但出于明显的效率原因,我不喜欢在每次击键后点击 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>
  );
}
javascript reactjs lodash debouncing
1个回答
0
投票

发生这种情况是因为您在

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 调用。

© www.soinside.com 2019 - 2025. All rights reserved.