昨天完成我的每日文章(是的,我每天都会发布一篇关于前端开发的新文章,所以如果你想要每天的代码丸,请务必关注 😉),我去编码了一点......我开始为我正在构建的副项目编写一些自定义挂钩(我在我的 Twitter 上谈论它: @thenaubit)。
我意识到有很多非常有用的自定义 React 钩子。因此,我开始了一个新系列,我将在其中发布其中的一些内容(由我编码或在 Internet 上找到并转换为 TypeScript)。
如果你做过让你引以为豪的事情,请随时在评论中分享要点链接,我会把它添加到下面的文章中!
1️⃣ 使用WindowSize Hook
我很确定您在您从事的某些项目中需要获取用户窗口的宽度和高度。
好吧,现在你有了一个钩子,所以你可以比以前更容易地做到这一点!
import { useState, useEffect } from "react";
interface WindowSize {
width: number;
height: number;
}
const useWindowSize = (): WindowSize => {
const [windowSize, setWindowSize] = useState<WindowSize>({
width: window.innerWidth,
height: window.innerHeight,
});
useEffect(() => {
const handleResize = () => {
setWindowSize({
width: window.innerWidth,
height: window.innerHeight,
});
};
window.addEventListener("resize", handleResize);
return () => {
window.removeEventListener("resize", handleResize);
};
}, []);
return windowSize;
};
这个钩子在实现响应式设计时特别有用,并且由于某些原因,您需要在某些分辨率下运行某些特定代码!
2️⃣ 使用KeyPress Hook
下一个钩子让您检测何时按下特定键。这可以根据按下的键触发事件或动作。例如,关闭模式、提交表单……你知道,有很多选择。
import { useState, useEffect } from "react";
const useKeyPress = (targetKey: string): boolean => {
const [keyPressed, setKeyPressed] = useState(false);
const downHandler = ({ key }: KeyboardEvent) => {
if (key === targetKey) {
setKeyPressed(true);
}
};
const upHandler = ({ key }: KeyboardEvent) => {
if (key === targetKey) {
setKeyPressed(false);
}
};
useEffect(() => {
window.addEventListener("keydown", downHandler);
window.addEventListener("keyup", upHandler);
return () => {
window.removeEventListener("keydown", downHandler);
window.removeEventListener("keyup", upHandler);
};
}, []);
return keyPressed;
};
当然,我会举例说明如何使用它:
const closeModalKeyPress = useKeyPress("Escape");
是的,就这么简单。
3️⃣ 使用Interval Hook
这个钩子允许你使用著名的 setInterval 函数作为一个钩子!和 setInterval 函数一样,这个钩子有很多用途,比如动画、定期更新数据,甚至设置计时器。
import { useState, useEffect, useRef } from "react";
const useInterval = (callback: () => void, delay: number | null) => {
const savedCallback = useRef<() => void>();
useEffect(() => {
savedCallback.current = callback;
}, [callback]);
useEffect(() => {
function tick() {
savedCallback.current && savedCallback.current();
}
if (delay !== null && delay > 0) {
let id = setInterval(tick, delay);
return () => clearInterval(id);
} else {
tick();
}
}, [delay]);
};
你可以像这样使用这个钩子:
const [count, setCount] = useState(0);
useInterval(() => {
setCount(count + 1);
}, 1000);
4️⃣ 使用Debounce Hook
现在我们将讨论一个用于去抖动的功能。如果你不知道它是什么,基本上该函数只有在经过一定时间后才会被执行而不会被调用。
这很有用,例如,对于限速 API 调用或输入更改时的状态更新,例如当您在搜索输入中键入一些文本时。
import { useEffect, useRef } from 'react';
export function useDebounce(callback:Function, timeout: number = 200, deps: Array<any> = []) {
const data = useRef({ firstTime: true });
useEffect(() => {
const { firstTime, clearFunc } = data.current;
const handler = setTimeout(() => {
if (clearFunc && typeof clearFunc === 'function') {
clearFunc();
}
data.current.clearFunc = callback();
}, timeout);
return () => {
clearTimeout(handler);
};
}, [timeout, ...deps]);
}
export default useDebounce;
一个用法示例是:
const [inputValue, setInputValue] = useState("");
useDebounce(() => {
// make API call
}, 500);
5️⃣使用油门挂钩
之前是debounce hook,现在轮到油门hook了。
顾名思义,它是一个用来限制函数的钩子。这意味着它将每隔指定的时间间隔执行一次。这对于防止快速连续触发过多的 API 调用或事件很有用。
import { useEffect, useRef } from 'react';
export const useThrottle = (callback:Function, delay: number = 200, deps: Array<any> = []) => {
const lastRan = useRef(Date.now());
useEffect(
() => {
const handler = setTimeout(function() {
if (Date.now() - lastRan.current >= delay) {
callback();
lastRan.current = Date.now();
}
}, delay - (Date.now() - lastRan.current));
return () => {
clearTimeout(handler);
};
},
[delay, ...deps],
);
};
export default useThrottle;
一个例子是:
const [inputValue, setInputValue] = useState("");
useThrottle(() => {
// make API call
}, 500);
好吧,我们到了文章的结尾,但在您开始之前,我想多说几句关键的事情。
第一个是这些钩子是示例,就像您在 Internet 上找到的任何其他代码一样。您不应该只是将它们复制并粘贴到您的项目中。你应该阅读它们,理解它们并改进它们!
话虽如此,我真的很喜欢写这样的文章,所以如果你也喜欢它们,一定要关注并喜欢它们。那样,我就会知道人们想要更多,我们就会拥有更多。哦,正如我在文章开头所说的那样,如果您有一些喜欢的小钩子,请在这里分享;我想在下一篇文章中添加它们!