自定义Hook的作用
将组件逻辑提取到可重用的函数中
实现一个自定义Hook抽象鼠标跟踪器
创建一个文件useMousePosition
import {useState,useEffect} from 'react'
// 自定义hook必须要use开头
// 在两个组件中使用相同的hook不会共享state
const useMousePosition = () =>{
const [position,setPosition] = useState({x:0,y:0})
useEffect(()=>{
console.log("add Effect",position.x);
const updateMouse = (e:MouseEvent)=>{
setPosition({x:e.clientX,y:e.clientY})
}
document.addEventListener('mousemove', updateMouse)
return ()=>(
// 清楚前面的click事件的Effect
// console.log(1)
document.removeEventListener('click', updateMouse)
)
},[])
return position
}
export default useMousePosition
在另一个文件中的使用
import useMousePosition from './Hook/useMousePosition'
....
return (
<div style={{margin:"auto 0"}}>
<p>X:{position.x},y:{position.y}</p>
<LikeBUtton></LikeBUtton>
{/* <MouseTrack></MouseTrack> */}
</div>
);
注意在两个相同的组件中使用hook是不会共享state的
实现一个自定义点击按钮重新加载图片的hook
创建文件useURLLoader.tsx
import {useState,useEffect} from 'react'
import axios from 'axios'
const useURLLoader = (url:string,deps:any[]=[])=>{
const [data,setData] = useState<any>(null)
const [loading,setLoading] = useState(true)
useEffect(()=>{
setLoading(true)
axios.get(url).then(res=>{
setData(res.data)
// console.log(data);
})
setLoading(false)
// console.log(loading)
},[deps])
return [data,loading]
}
export default useURLLoader
在需要使用的地方这样使用
import useURLLoader from './Hook/useURLLoader'
interface IShowResult {
message:string;
status:string;
}
const [show,setShow] = useState(true)
const [data,loading] = useURLLoader('https://dog.ceo/api/breeds/image/random',[show])
const dogRes = data as IShowResult
return ( <button onClick={()=>{setShow(!show)}}>Toggle Tracker</button>
{loading?<p>读取中...</p>:<img src={dogRes&&dogRes.message} alt="图片"></img>}
)