1.封装useEffect,后面依赖的[]被省略了。
// 复用useEffect
export const useMount = (callback) => {
useEffect(() => {
callback()
},[])
}
// 使用
// 只在页面渲染时执行一次获取users
useMount(() => {
fetch(`${apiUrl}/users`).then(async response => {
if (response.ok) {
setUsers(await response.json())
}
})
})
注意,定义custom hook时名字必须以use开头,否则eslint会报错,因为不管是自己定义的hook还是react自带的hook都只能在组件中或其他hook中运行。
2.定义搜索框防抖debounce,只会执行最后的定时任务。
注:节流是同一时间只能执行一个任务,执行完毕后才能执行下一个,原理是定义一个状态,在执行任务前后改变状态,执行体通过判断此状态可以判断该函数是否在执行,从而决定是否执行。
// debounce防抖示例
export const debounce = (func, delay) => {
let timeout
return ()=> {
if(timeout){
clearTimeout(timeout)
}
timeout = setTimeout(() => {
func()
}, delay);
}
}
在项目在实际运用:
export const useDebounce = (value, delay) => {
// 定义一个内部state hook来对传入进来的参数value进行管理
const [debounceValue, setDebounceValue] = useState(value)
// 每当输入框传入的value变化时,Effect hook就会设置一个定时器,
// 在delay时间后操作state hook更新从外界传入的debounceVlue中的value值,
// 当此定时器执行完毕后 Effect再清理定时器 最后将处理后的value return出去
useEffect(() => {
const timeout = setTimeout(() =>
setDebounceValue(value)
, delay)
return () => clearTimeout(timeout)
}, [value, delay])
return debounceValue
}
注:每次value更新,就会重新触发下一个useEffect,这时就会执行return里的函数,意思就是每个useEffect触发时,将会清理掉上一个useEffect定义的定时器。
修改请求时的Effect hook
const debounceParam = useDebounce(param, 2000)
//
useEffect(() => {
//请求接口
fetch(`${apiUrl}/projects?${qs.stringify(cleanObject(debounceParam))}`).then(async response => {
if (response.ok) {
// json()返回一个被解析为JSON格式的promise对象
setList(await response.json())
}
})
}, [debounceParam])