【React】常用的自定义 hooks
自定义 hooks 或者第三方 hooks,抽离公共部分,复用代码。
修改页面标题
import React, {useEffect} from 'react';function useTitle(title) {useEffect(() => {document.title = title;}, []);
}export default useTitle;
获取鼠标位置
import React, {useEffect, useState} from 'react';function useMouseMove() {const [x, setX] = useState(0)const [y, setY] = useState(0)const handleMouseMove = (event) => {setX(event.clientX)setY(event.clientY)}useEffect(() => {window.addEventListener('mousemove', handleMouseMove)return () => {window.removeEventListener('mousemove', handleMouseMove)}}, [x, y]);return {x, y};
}export default useMouseMove;
异步获取数据
import React, {useEffect, useState} from 'react';function getInfo():Promise<string> {return new Promise(resolve => {setTimeout(() => {resolve(Date.now().toString())}, 1500)})
}function useGetInfo() {const [loading, setLoading] = useState(true)const [info, setInfo] = useState('')useEffect(() => {getInfo().then(info => {setInfo(info)setLoading(false)})}, []);return { loading, info }
}export default useGetInfo;
import useTitle from "./hooks/useTitle.tsx";
import useMouseMove from "./hooks/useMouseMove.tsx";
import useGetInfo from "./hooks/useGetInfo.tsx";function App() {useTitle('React Demo')const {x, y} = useMouseMove()const {loading, info} = useGetInfo()return (<><h1>React Demo</h1><div>鼠标位置:{x} {y}</div><div>异步获取当前时间:{loading ? '加载中' : info}</div></>)
}export default App
第三方 hooks
常见的有 ahooks 或者 react-use。
ahooks - React Hooks Library - ahooks 3.0
https://github.com/streamich/react-use
我们上面的 hooks 几乎在这些第三方库中都可以找到。
Hooks 规则
-
命名规则:
- Hook 必须
useXxx
格式来命名。
- Hook 必须
-
调用位置
- 组件内部
- 其他 Hook 内部
组件外部,或一个普通函数中,不能调用 Hook
-
顺序一致
Hook 必须是组件“第一层代码”
- Hook 不可放在 if 等条件语句中 ( 或者前面有 return ,也算是条件 )
- Hook 不可放在 for 等循环语句中
-
闭包陷阱
当异步函数中获取 state 时,可能不是最新的 state 值。
解决方案:替换为 useRef
—— 但 ref 变化不会触发 rerender ,所以得结合 state 一起。详情见:【React】React Hooks-CSDN博客