1、未使用debounce
import React, { useEffect, useRef, useState } from 'react';
import { Input, message } from 'antd';
import styled from '@emotion/styled'
const UseDebounce = () => {
const [inputVal, setInputVal] = useState('')
useEffect(() => {
message.info(`参数为${inputVal},请求数据。。。`)
}, [inputVal])
return (
<div>
<InputWrap value={inputVal} onChange={e => setInputVal(e.target.value)} />
</div>
)
}
const InputWrap = styled(Input)`
width: 200px;
margin-top: 30px;
margin-left: 30px;
当连续输入时,效果如下图所示:
2、自定义hook
新建useDebounce.ts文件,内容如下:
import { useEffect, useState } from 'react'
export const useDebounce = <T>(value: T, delay: number) => {
const [param, setParam] = useState(value)
useEffect(() => {
const timeout = setTimeout(() => setParam(value), delay)
return () => clearTimeout(timeout)
}, [value, delay])
return param
}
父组件中引入
import React, { useEffect, useRef, useState } from 'react';
import { Input, message } from 'antd';
import styled from '@emotion/styled'
import { useDebounce } from 'src/hooks/useDebounce';
const UseDebounce = () => {
const [inputVal, setInputVal] = useState('')
const debounceParam = useDebounce(inputVal, 300)
useEffect(() => {
message.info(`参数为${inputVal},请求数据。。。`)
}, [debounceParam])
return (
<div>
<InputWrap value={inputVal} onChange={e => setInputVal(e.target.value)} />
</div>
)
}
const InputWrap = styled(Input)`
width: 200px;
margin-top: 30px;
margin-left: 30px;
`
export default UseDebounce
连续输入后,效果如下:
3、总结
实现debounce方案有很多,自定义hook的方式更加直观且简单。其原理主要运用了useEffect执行机制。每次value值变化,开始设置一个定时器,当依赖变化时,就清除上一个定时器,并新建一个定时器。