第一课:React的Hooks

npx是什么?

  • 避免安全全局模块

Hook规则

  • 只在最顶层使用Hook
  • 只在React函数中调用Hook

定义函数组件

javascript 复制代码
interface IHelloProps {
    message?: string
}

// const Hello = (props: IHelloProps) => {
//     return (
//         <div>
//             <h1>{props.message}</h1>
//         </div>
//     )
// }

const Hello: React.FC<IHelloProps> = (props) => {
    return (
        <div>
            <h1>{props.message}</h1>
        </div>
    )
}

export default Hello

hook的学习

老的hook

  • componetDidMount()
  • componetDidUpdate()
  • componetUnMonunt()
    新的Hook完全拥抱函数。

State Hook

在函数组件内部使用hook

  • 改变组件状态,组件里面记住状态的值。
javascript 复制代码
import React, {useState} from "react";
const LikeButton: React.FC = () => {
    const [obj, setObj] = useState({like: 0, on: true})
    return (
        <>
            <button onClick={() => setObj({like: obj.like + 1, on: obj.on})}>
                {obj.like}👍
            </button>
            <button onClick={() => setObj({like: obj.like, on: !obj.on})}>
                {obj.on ? 'ON' : 'OFF'}
            </button>
        </>
    )
}
export default LikeButton

Effect Hook

  • 无需清除的Effect
  • 使用useEffect完成标题的更新
  • 在老的class 中使用DiaMount 和 DidUpdate两个方法里面执行。

useEffect 在每次dom模型渲染之后,都会执行触发。

javascript 复制代码
    useEffect(() => {
        document.title = `点击了${obj.like}次`
    });
需要清除的Effect

注册的dom事件,要及时清除,否则会在组件每次渲染的时候,都会注册一次。

javascript 复制代码
import {useEffect, useState} from "react";


const MouseTracker: React.FC = () => {
    const [positions, setPositions] = useState({x: 0, y: 0})

    useEffect(() => {
        console.log('add effect:', positions.x)
        const updateMouse = (e: MouseEvent) => {
            console.log("inner")
            setPositions({x: e.clientX, y: e.clientY})
        }
        document.addEventListener('click', updateMouse)

        return () => {
            console.log('remove effect:', positions.x)
            document.removeEventListener('click', updateMouse)
        }
    });
    console.log('before render', positions.x)
    return (
        <p>鼠标位置:{positions.x}, {positions.y}</p>
    )
}

export default MouseTracker;
控制useEffect 的执行

可以使用最后一个参数数组[], 控制useEffect的执行时机,只有这些值发生变化,才会重新执行一次useEffect()

javascript 复制代码
    useEffect(() => {
        console.log('add button effect:', obj.like)
        document.title = `点击了${obj.like}次`
    }, [obj.like, on]);

自定义Hook

自定义hooks,必须以use开头。然后可以在多个组件中引入,互不干扰。

javascript 复制代码
import {useEffect, useState} from "react";

const useMousePosition = () => {
    const [positions, setPositions] = useState({x: 0, y: 0})

    useEffect(() => {
        console.log('add use effect:', positions.x)
        const updateMouse = (e: MouseEvent) => {
            console.log("use inner")
            setPositions({x: e.clientX, y: e.clientY})
        }
        document.addEventListener('mousemove', updateMouse)

        return () => {
            console.log('remove use  effect:', positions.x)
            document.removeEventListener('mousemove', updateMouse)
        }
    }, []);
    return positions
}

export default useMousePosition

在其它组件中使用:

  • 导入
    import useMousePosition from ".../hooks/useMousePosition";
  • 使用里面的值
    const positions = useMousePosition()

HOC 高阶组件(不太好的组件)

  • 可以对已有的组件进行转换成新组件。
  • 本身是一个函数,接收一个函数,返回另一个函数。

自定义hook完成HOC类似功能(更简单)

自定义:useURLLoader 功能。

javascript 复制代码
import axios from 'axios'
import {useEffect, useState} from "react";

const useURLLoader = (url: string, deps: any[] = []) => {

    const [data, setData] = useState<any>(null)
    const [loading, setLoading] = useState<boolean>(false)

    useEffect(() => {
        setLoading(true)
        axios.get(url).then(result => {
            setData(result.data)
            setLoading(false)
        })
    }, deps);
    return [data, loading]
}

export default useURLLoader


interface IShowResult {
    message: string
    status: string
}


通过count 控制组件再次重新请求
const [data, loading] = useURLLoader('https://dog.ceo/api/breeds/image/random', [count])
// data 是any 类型,强制转化成IShowResult
const dogResult = data as IShowResult

useRef(改变ref里面的current值,不会重新渲染dom)

修改Ref不会触发组件的重新渲染。

  • 使用用 ref 引用一个值
  • 通过 ref 操作 DOM
  • 避免重复创建 ref 的内容

特点:

  • 改变 ref.current 属性时,React 不会重新渲染组件。 所以不适合保存期望展示在屏幕上的信息。
  • 可以在 Effect 中读取和写入 ref
  • 可以在事件处理程序中读取和写入 ref
  • 不要在渲染期间写入或者读取 ref.current
javascript 复制代码
    const likeRef = useRef(0)
    - current 泛型的T
    
    function handleAlertClick() {
        setTimeout(() => {
            alert(`点击了${likeRef.current}次`)
        }, 3000)
    }
    
复制代码
useRef 可以模拟操作dom
javascript 复制代码
    const domRef = useRef<HTMLInputElement>(null)
    useEffect(() => {
        if(domRef && domRef.current){
            domRef.current.focus()
        }
    });
    <input type="text" ref={domRef}/>
相关推荐
沄媪3 小时前
Web渗透测试详细技术总结(基于Kali Linux)
linux·前端·渗透测试·web
东东5163 小时前
基于SSM的宠物医院预约挂号系统的设计与实现vue
java·前端·javascript·vue.js·毕设
黑贝是条狗4 小时前
mormor2与vue搭建一个博客系统
前端·javascript·vue.js
拔刀能留住落樱吗、4 小时前
代码诊疗室——疑难Bug破解战
前端·html
GISer_Jing4 小时前
Taro 5.0 深度:跨端开发的架构革新与全阶实践指南
前端·react.js·taro
宁雨桥4 小时前
我开源了一个 Chrome 插件:一键总结网页为 Markdown
前端·chrome·开源
南夏一木子4 小时前
Vue学习 —— Axios异步通信
前端·vue.js·学习
GISer_Jing4 小时前
Taro 5.0 小白快速上手指南:从0到1实现跨端开发
前端·react.js·taro
熊猫钓鱼>_>4 小时前
【开源鸿蒙跨平台开发先锋训练营】React Native 性能巅峰:HarmonyOS极致优化实战手册
react native·react.js·华为·开源·harmonyos·鸿蒙·openharmony