预期行为
我有一个搜索输入,当用户键入一个单词时,我想等待1秒钟,然后才能使用appolo useLazyQuery重新获取数据。但是,如果用户在1s之前再次开始键入,则应该重置计时器。
所以我正在使用setTimeOut和clearTimeout,但是我注意到appollo为每个笔划发送了一个请求。
有一种方法可以防止多次重新引用,并且仅在用户停止输入时才在1秒后发送请求
import React, { useState } from 'react'
import { useLazyQuery } from '@apollo/react-hooks'
import {GET_BUSINESSES} from '../../../qraphQl/businessType'
const SearchTool = () => {
const [name, setName] = useState('')
const [busSug, setBusSug] = useState({busSug:[], showBusSug: false})
// prevent sending many hhtp request
const [getBusiness , { loading , data, error }] = useLazyQuery(GET_BUSINESSES)
let typingWaitTimer = null
const handleNameChange = (event) => {
clearTimeout(typingWaitTimer)
const val = event.target.value
setName(()=> val)
typingWaitTimer = setTimeout(() => getBusiness( {variables: { query: name }} ) , 1000)
}
答案 0 :(得分:1)
您可以使用效果钩子,这样对于每个超时设置,最后一个将被清除/覆盖。
看看下面的代码片段:您可以验证它仅在停止键入整个1秒钟时才会登录到控制台。
import React, { useEffect, useState } from "react";
// mocked those just for demonstration, but it
// should work with the real graphql hook. Feel
// free to ignore this part
const GET_BUSINESSES = "your graphql file";
const useLazyQuery = () => {
return [({ variables: { query } }) => console.log(`query: ${query}`)];
};
const DELAY_IN_MS = 1000;
export default function App() {
const [name, setName] = useState("");
// omitting { data, error, loading } here just
// because they aren't used in the example
const [getBusiness] = useLazyQuery(GET_BUSINESSES);
// every time `name` changes, this hook will be
// triggered
useEffect(() => {
const handler = setTimeout(() => {
getBusiness({ variables: { query: name } });
}, DELAY_IN_MS);
// this will make sure that the timeout will
// be cleared if the effect gets called again
return () => {
clearTimeout(handler);
};
}, [name, getBusiness]);
const handleNameChange = (event) => {
setName(event.target.value);
};
return <input value={name} onChange={handleNameChange} />;
}
顺便说一下,在调用函数之前的短时间间隔的名称称为 debounce 。 This blog post很好地解释了如何使用React钩子实现去抖,而我的示例基于此。