hooks

145 阅读2分钟

什么是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;