你应该使用的 10 个 React 社区钩子
React 可能是前端开发中最好的工具,React 本身非常强大,但如果你在项目中使用这些社区钩子,不仅你的代码会更加清晰和简洁,而且性能也会更高,并且可以避免冗余重新渲染和性能问题的可能性。
当谈到编程时,您应该始终努力追求干净的代码,以下是我推荐的 10 个社区钩子,它们将帮助您编写更干净、更高效的代码:
1. React hook 表单
如果我们只想使用 React 来创建一个表单,那么为每个单独的输入创建状态并更新它们会非常令人沮丧,更不用说验证和随之而来的所有脏代码了。
React 表单钩子让您仅使用几行简单的代码就可以处理所有繁重的工作,您的代码将更加简洁,您可以验证数据并处理错误,并以最少的努力将它们显示给用户。
React hook 表单是一个很大的模块,请在此处阅读更多内容以了解其各种功能。
示例用法:
import { useForm } from "react-hook-form"
export default function App() {
const {
register,
handleSubmit,
watch,
formState: { errors },
} = useForm()
const onSubmit = (data) => console.log(data)
console.log(watch("example")) // watch input value by passing the name of it
return (
/* "handleSubmit" will validate your inputs before invoking "onSubmit" */
<form onSubmit={handleSubmit(onSubmit)}>
{/* register your input into the hook by invoking the "register" function */}
<input defaultValue="test" {...register("example")} />
{/* include validation with required or other standard HTML validation rules */}
<input {...register("exampleRequired", { required: true })} />
{/* errors will return when field validation fails */}
{errors.exampleRequired && <span>This field is required</span>}
<input type="submit" />
</form>
)
}
2. useUpdateEffect
有时在您的 React 应用程序中,您只想在某个状态更新时触发某个函数,这基本上就是仅在更新时使用 useEffect。
无需使用任何第三方钩子即可实现这一点,但它会使您的代码变得有点混乱。
以下是我们以前的做法(不使用库):
const mounted = useRef(false)
useEffect(() => {
if (mounted.current) {
// this function will not be called on the first render
} else {
mounted.current = true
}
}, []) // it will be called everytime the dependecty list is updated
这是一种更简洁的方法,即使用react-use
包含许多其他优秀钩子的库。
import { useUpdateEffect } from "react-use"
const Home = () => {
useUpdateEffect(() => {
// will not run on the first render
console.log("Runs only if the state updates")
}, [fName])
return ( ...)
}
3. 使用CopyToClipboard
这个钩子是不言自明的,它返回一个状态和一个函数来更新状态并将该状态复制到剪贴板。
状态将具有用户复制到剪贴板的字符串的值(请注意,我们无法从用户剪贴板中读取已保存的文本,我们只能获取用户从我们的网站复制的文本的值),如果函数运行时发生某些错误,它还将具有错误属性。
实现起来也很简单:
import { useCopyToClipboard } from "react-use"
const App = () => {
const [text, setText] = useState("")
const [state, copyToClipboard] = useCopyToClipboard()
return (
<div>
<input value={text} onChange={(e) => setText(e.target.value)} />
<button type="button" onClick={() => copyToClipboard(text)}>
copy text
</button>
</div>
)
}
4. 使用本地存储
与浏览器本地存储的交互有时会令人沮丧,因为只有在组件安装时才能访问本地存储,在这种情况下,您只需要在useEffect
钩子内使用本地存储,这可能会导致代码混乱,这就是使用这个钩子的地方。
useLocalStorage 钩子有 2 个参数,第一个参数是您想要在本地存储中设置的项目的键,第二个参数是该项目的初始值,这意味着如果该项目在用户本地存储中为空,我们将使用该值作为初始值。
该钩子还返回一个包含 3 个项目的数组,第一个是该项目的值,第二个是更新该值的函数,第三个和最后一个是从本地存储中删除该项目的函数。
示例用法:
import { useLocalStorage } from "react-use"
export default function App() {
const [token, setToken, removeToken] = useLocalStorage("token", "foo") // initial value is foo
return (
<div>
<div>Value: {token}</div>
<button onClick={() => setToken("bar")}>bar</button>
<button onClick={() => setToken("baz")}>baz</button>
<button onClick={() => removeToken()}>Remove</button>
</div>
)
}
5. useHover
这个钩子用于知道特定元素是否悬停,但用法与其他钩子略有不同。
您向它传递一个 JSX 元素,它将返回一个包含两个项目的数组,第一个是您应该在 JSX 中使用的元素,第二个是 isHovered 布尔状态。
方法如下:
import { useHover } from "react-use"
const App = () => {
// you can use the hovered argument from the function here
const element = (hovered: boolean) => (
<p>Sample text which is {hovered ? "hovered" : "not hovered"}</p>
)
// or you can get the hovered state from the hook
const [textElement, isHovered] = useHover(element)
return <div>{textElement}</div>
}
6. useIdle
这个钩子用于知道用户是否处于空闲状态或用户处于活动状态,你可以传递两个参数,第一个是决定用户是否处于空闲状态需要经过的毫秒数,第二个是你可以添加的初始状态,true
或者false
默认情况下设置为false
import { useIdle } from "react-use"
const App = () => {
const isIdle = useIdle(3000) // this will return true if the user has gone idle for more than 3 seconds
return <div>{isIdle ? "User is idle" : "User is not idle"}</div>
}
7. 使用ClickAway
当我们想要在特定 UI 组件外部单击时触发某个函数时,此钩子很有用,例如,我们有一个打开的模态框,并且我们想要在用户单击模态框外部时关闭该模态框,基本上我们的意思是,如果用户单击模态框以外的任何其他地方,我们想要运行一个函数(在本例中是关闭模态框)
import { useClickAway } from "react-use"
const App = () => {
const ref = useRef(null)
useClickAway(ref, () => {
console.log("OUTSIDE CLICKED")
})
return (
<div
ref={ref}
style={{
width: 200,
height: 200,
background: "red",
}}
/>
)
}
8- useDebounce
这个钩子的主要用例是当我们想要从 API 中搜索一些查询,但我们不想在用户每次输入单词时都发送请求,因为在这种情况下,我们会向 API 发送太多冗余请求并使服务器过载,这不是一个可扩展的解决方案。
我们的做法是等待用户完成输入,然后发送请求,这是理想的。
import { useDebounce } from "react-use"
const App = () => {
const [input, setInput] = useState("")
const [loading, setLoading] = useState(false)
useDebounce(
() => {
setLoading(true)
// you should now send the request to the api
// ...
// ...
setLoading(false)
},
500,
// the amount of milliseconds to wait before firing the function
[input] // the dependencies to watch for changes
)
return <input value={input} onChange={(e) => setInput(e.target.value)} />
}
9- useWindowSize
这个钩子返回屏幕的高度和宽度,并且会在屏幕尺寸发生变化时自动更新。
import { useWindowSize } from "react-use"
const App = () => {
// gets the height and width of the window
const { width, height } = useWindowSize()
return (
<div>
<div>width: {width}</div>
<div>height: {height}</div>
</div>
)
}
10-使用Swr
这个钩子使得在安装组件时处理请求变得容易。
该钩子接受两个参数,第一个是请求的 url,第二个是 fetcher 函数,它可以是任何向服务器发送请求的函数。
然后它会返回isValidating
、error
和响应数据状态,该isValidating
状态的工作方式与任何加载状态一样。
它还会为您提供一个名为的函数mutate()
,您可以使用该函数再次重新获取 API,这在您改变某些数据时很有用,例如,您正在从待办事项列表中删除待办事项,在该操作成功后,您可以mutate()
再次调用该函数来获取最新数据。
下面的示例只是在组件安装时获取一些数据。
import useSWR from "swr"
const fetcher = (url: string) => fetch(url).then((r) => r.json())
const App = () => {
const { data, mutate, error, isValidating } = useSWR(
"https://jsonplaceholder.typicode.com/todos/1",
fetcher
)
if (error) return <div>failed to load</div>
if (!data) return <div>loading...</div>
return <div>Todo title: {data.title}!</div>
}
这些是我在这篇文章中提出的十大钩子,我希望你觉得它们有用,如果觉得有用,请考虑分享这篇文章。
感谢您阅读这篇文章,如果您有任何问题或意见,请随时在推特上联系我,我也每天在推特上发布内容,所以请确保您也关注我。
文章来源:https://dev.to/dcodes/10-react-community-hooks-1h6c