什么是hooks?
- 消息处理的一种方法,用来监视指定程序
- 函数组件中需要处理副作用,可以用钩子把外部代码“钩”进来
- 常用钩子:useState,useEffect,useContext,useReducer
- 自定义hooks一律使用use前缀命名:useXXX
hooks本质
- 一类特殊的函数,为你的函数型式组件(functional component) 注入特殊的功能
状态钩子:useState()
const [count,setCount] = useState(0)
-
react自带的一个hook函数,声明组件状态
-
参数可以设置state的初始值(initial state)
-
返回值是一个只有两个元素的数组:[状态,状态更新函数]
副作用钩子:useEffect()
useEffect(()=>{
document.title = `点击${count}次`
},[count])
//鼠标事件的绑定监听与移除监听
useEffect(()=>{
const updateMouse = (e :MouseEvent)=>{
setPositions({x:e.clientX,y:e.clientY})
}
document.addEventListener('click',updateMouse)
return ()=>{
document.removeEventListener('click',updateMouse)
}
},[])
- ==数组里的值改变时,才会重新执行useEffect==
- 可以取代生命周期函数 componentDidMount,componentDidUpdate和componentWillUnmount
- 给函数式组件添加副作用(side effect)
全局组件通信:useContext()
App.tsx 提供者
import React, {useState} from 'react';
interface IThemeProps {
[key: string]: { color: string, background: string }
}
const themes: IThemeProps = {
'light': {
color: '#000',
background: '#eee'
},
'dark': {
color: '#fff',
background: '#222'
}
}
export const ThemeContext = React.createContext(themes.light)
function App() {
return (
<div className="App">
<ThemeContext.Provider value={themes.light}>
...
</ThemeContext.Provider>
</div>
)
}
其他组件 消费者
import React, {useContext} from "react";
import {ThemeContext} from './../../App'
const LikeButton:React.FC = () =>{
const theme = useContext(ThemeContext)
console.log(theme)
const style = {
background:theme.background,
color:theme.color,
width:'100px',
height:'30px',
lineHeight:'30px',
fontSize:'12px'
}
return (
<div style={style}>我是likebutton</div>
)
}
export default LikeButton
全局状态:useReducer()
处理回掉副作用:useCallback()
引用对象:useRef()
常用于dom操作
import React, {useEffect, useRef, useState} from "react";
const LikeButton:React.FC = () =>{
const domRef = useRef<HTMLInputElement>(null)
useEffect(()=>{
if (domRef && domRef.current){
domRef.current.focus()
}
})
return (
<input type="text" ref={domRef}/>
)
}
export default LikeButton
useLayoutEffect()
useDebugValue()
自定义hooks
src下面创建hooks文件夹
创建文件名必须已use开头命名
useURLLoader.tsx
import React, {useEffect, useState} from 'react'
import axios from 'axios'
const useURLLoader = (url:string,deps:any[]=[])=>{
const [data,setData] = useState<any>(null)
const [loading,setLoading] = useState(false)
useEffect(()=>{
setLoading(true)
axios.get(url).then(result=>{
setData(result.data)
setLoading(false)
})
},deps)
return [data,loading]
}
export default useURLLoader
引用 App.tsx
import React, {useState} from 'react';
import useURLLoader from "./hooks/useURLLoader";
interface IResult {
message:string,
status:string
}
function App() {
const [show,setShow] = useState(true)
const [data,loading] = useURLLoader('https://dog.ceo/api/breeds/image/random',[show])
const dogResult = data as IResult
return (
<div className="App">
{loading?<p>数据加载中...</p>:<img src={dogResult && dogResult.message} />}
<button onClick={()=>{setShow(!show)}}>重置图片</button>
</div>
);
}
export default App;