自定义hook: 用来封装复用的逻辑,,自定义hook是以use开头的普通函数,,将组件中可复用的状态逻辑抽取到自定义的hook中,简化组件代码
常见自定义hook例子:
封装一个简单的计数器
import {useState} from "react";
function useCounter(initialValue:number){
const [count, setCount] = useState(0)
const increment = ()=>setCount(prev=>prev+1)
const decrement = ()=>setCount(prev=>prev-1)
const reset = ()=>setCount(initialValue)
return {count,increment,decrement,reset}
}
export default useCounter
封装一个自动监听网页窗口变化的hooks
import {useEffect, useState} from "react";
function useWindowSize(){
const [size, setSize] = useState({
width:window.innerWidth,
height:window.innerHeight
})
useEffect(() => {
const handleResize = ()=>{
setSize({
width: window.innerWidth,
height: window.innerHeight
})
}
window.addEventListener("resize",handleResize)
return ()=> window.removeEventListener("resize",handleResize)
}, []);
return size
}
export default useWindowSize
封装一个网络请求的hooks,返回请求的状态
import {useEffect, useState} from "react";
import axios from "axios";
interface FetchResult<T>{
data:T | null,
loading:boolean,
error: Error | null
}
function useFetch<T = any>(url:string):FetchResult<T>{
const [data, setData] = useState<T | null>(null)
const [loading, setLoading] = useState(true)
const [error, setError] = useState<Error | null>(null)
useEffect(() => {
const fetchData = async ()=>{
try {
const response = await axios.get(url)
console.log(response)
setData(response.data)
} catch (e) {
setError(e as Error)
} finally {
setLoading(false)
}
}
fetchData()
}, [url]);
return {data,loading,error}
}
export default useFetch
hook设置获取localStorage
import {useState} from "react";
function useLocalStorage<T>(key:string,initialValue:T | null){
const [storeValue, setStoreValue] = useState(()=>{
try {
var item = window.localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue
} catch (e) {
console.log(e)
return initialValue
}
})
const setValue = (val:T | null)=>{
try {
setStoreValue(val)
if (val){
window.localStorage.setItem(key, JSON.stringify(val))
}else{
window.localStorage.removeItem(key)
}
} catch (e) {
console.log(e)
}
}
return [storeValue,setValue] as const
}
export default useLocalStorage
调用hook:
import useCounter from "./useCounter";
import useWindowSize from "./useWindowSize";
import useFetch from "./useFetch";
import useLocalStorage from "./useLocalStorage";
function CustomHook(){
const {count,increment,decrement,reset} = useCounter(10)
const {width,height} =useWindowSize()
const {data,loading,error} = useFetch("http://localhost:9090/hello")
const [token,setToken] = useLocalStorage<String | null>("token",null)
if (loading) return <div>loading ....</div>
if (error) return <div>error: {error.message}</div>
return (
<div>
<div> {width}</div>
<div> {height}</div>
{count}
<button onClick={increment}>increment</button>
<button onClick={decrement}>decrement</button>
{data}
<h3> token is :{token}</h3>
<button onClick={()=>setToken("123")}>123</button>
</div>
)
}
export default CustomHook