ReactHook技巧
创始人
2024-04-11 20:25:10
0

ReactHook技巧

文章目录

    • ReactHook技巧
    • 一 概念
    • 二 useState
    • 三 useEffect
      • 3.1 无需清除副作用(**Effect**)
      • 3.2 需要清除副作用(**Effect**)
      • 3.3 控制(**Effect**)调用次数
    • 四 自定义hook
      • 4.1 hoc

一 概念

1.什么是hook?

2.为什么要用hook?

-: 为函数组件提供状态管理能力, 扩展
-: 在Function组件中勾入更多React 特性, 以use开头

二 useState

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qcvXgPA7-1669130695588)(micro%20_frontend/img/image-20221122232339894.png)]

./components/LikeButton.tsx

// rafc  tsrafe
import React, { useState } from 'react'const LikeButton: React.FC = () => {const [like, setLike] = useState(0)const [on, setOn] = useState(true)return (
) }export default LikeButton

改变函数内组件状态,在每次组件更新时候, 记住状态值

三 useEffect

纯函数:输入确定, 输出确定,无副作用

副作用:网络请求,手动dom操作,订阅数据来源, … 与纯函数界面渲染不同

两种场景:

    1. 无需清除副作用(Effect)
    1. 需要清除的副作用

3.1 无需清除副作用(Effect)

实现: 使用useEffect 修改DOM 完成标题更新

class实现:

在这里插入图片描述

hooks实现:

// rafc  tsrafe
import React, { useEffect, useState } from 'react'const LikeButton: React.FC = () => {const [like, setLike] = useState(0)...useEffect(()=>{//渲染和更新时候执行.document.title = `点击了 ${like} 次`})return (
...
) }export default LikeButton

3.2 需要清除副作用(Effect)

dom操作需要清除监听, 防止内存泄漏,卡顿页面

实现: 使用useEffect 完成鼠标跟踪器(鼠标移动时候显示鼠标位置)

原理:挂载document上, 点击click,修改state,当前值

在这里插入图片描述

class实现:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-H70K1K3G-1669133553231)(ReactHooks/image-20221122235414537.png)]

hooks实现:// 无依赖时候, 会多次重复调用effect 注册,执行

import React, { useEffect, useState } from 'react'const MouseTracker: React.FC = () => {const [position, setPosition] = useState({ x: 0, y: 0 })useEffect(() => {console.log('add effect',position.x);const updateMouse = (e: MouseEvent) => {console.log('inner');setPosition({x: e.clientX,y: e.clientY})}document.addEventListener('click', updateMouse)return () => {console.log('remove effect',position.x);document.removeEventListener('click', updateMouse)}})console.log('before render',position.x);return (
X :{position.x} {` `} Y :{position.y}
) }export default MouseTracker

*忘记react声明周期,重新接触react effect,发现每次渲染都会调用effect(有些浪费), 思考如何规避多次调用------>控制effect调用次数

3.3 控制(Effect)调用次数

避免每次渲染都会调用,控制次数

实现:控制useEffect的执行

修改前面例子代码 ,利用deps,依赖

function App() {const [show, setShow] = useState(true)return (
...

{show&&}...
); }export default App;

./components/MouseTracker.tsx

添加依赖项 [], 挂载, 卸载时候执行callback/ 避免一更新就执行回调

import React, { useEffect, useState } from 'react'const MouseTracker: React.FC = () => {const [position, setPosition] = useState({ x: 0, y: 0 })useEffect(() => {...document.addEventListener('click', updateMouse)return () => {...}},[])console.log('before render',position.x);return (...)
}export default MouseTracker

./components/LikeButton.tsx

添加[like] 依赖, 只在依赖项, like发生变化时候执行callback

// rafc  tsrafe
import React, { useEffect, useState } from 'react'const LikeButton: React.FC = () => {const [like, setLike] = useState(0)...useEffect(()=>{console.log('click')document.title = `点击了 ${like} 次`},[like])return (
) }export default LikeButton

四 自定义hook

  • 将组件逻辑提取到可重用函数

之前方式:hoc / render props

实现: 使用自定义hook 抽象鼠标跟踪器

注:

  1. 必须use 开头,否则识别不上
  2. 每次使用hook ,会在函数内部形成独立的调用空间, 不会共用

编写hooks

\hooks\useMousePosition.tsx

import React, { useEffect, useState } from 'react'const useMousePosition= () => {const [position, setPosition] = useState({ x: 0, y: 0 })useEffect(() => {const updateMouse = (e: MouseEvent) => {setPosition({x: e.clientX,y: e.clientY})}document.addEventListener('mousemove', updateMouse)return () => {document.removeEventListener('mousemove', updateMouse)}},[])return position
}export default useMousePosition

调用hooks , 并复用

在需要的地方引入

import React, { useState } from 'react';
...
import useMousePosition from './hooks/useMousePosition';function App() {const [show, setShow] = useState(true)+ const position = useMousePosition()return (
+ X :{position.x} {` `} Y :{position.y} ...
); }export default App;

在这里插入图片描述

4.1 hoc

发送请求 (展示Loading, 请求结束隐藏Loading), 实现逻辑复用

hoc: 高阶组件

高阶组件: 是一个函数,接受一个组件作为参数, 返回一个新组件

入参: 组件------>返回:新组件

实现:点击按钮,发送请求, 拿到结果后—>展示图片

/hocs/withLoader.tsx

// high order component
import React from 'react'
import axios from 'axios'interface ILoaderState {data: any,isLoading: boolean
}
interface ILoaderProps {data: any,
}
const withLoader = 

(WrappedComponent: React.ComponentType

, url: string) => {return class LoaderComponent extends React.Component, ILoaderState> {constructor(props: any) {super(props)this.state = {data: null,isLoading: false}}componentDidMount() {this.setState({isLoading: true,})axios.get(url).then(result => {this.setState({data: result.data,isLoading: false})})}render() {const { data, isLoading } = this.statereturn (<>{ (isLoading || !data) ?

data is loading

:...this.props as P} data={data} />})}} }export default withLoader

引入

App.tsx

import React, { useState } from 'react';
...
import withLoader from './hocs/withLoader';import './App.css';interface IShowResult {message:string,status:string,
}const DogShow:React.RC<{data:IShowResult}>=({data})=>{return (<>

Dog show:{data.status}

data.message}/>) }function App() {const WrappedDogShow = withLoader(DogShow, 'https://dog.ceo/api')return (
logo} className="App-logo" alt="logo" />......
); }export default App;

弊端:添加额外空节点, 逻辑 看着复杂

相关内容

热门资讯

中钢国际(000928)发布现... 截至2025年12月30日收盘,中钢国际(000928)报收于6.56元,较前一交易日下跌1.5%,...
明年“两新”政策方案发布 政策... 央视网消息(新闻联播):记者12月30日从国家发展改革委了解到,2026年优化实施“两新”政策方案正...
男子毒死9条宠物狗一审获刑4年... 极目新闻记者 曹雪娇 此前,北京首例宠物中毒刑事公诉案一审宣判,被告因投放危险物质罪被判有期徒刑4年...
黑龙江一个调解案例入选国家典型... 人民网哈尔滨12月30日电 (记者张齐)近日,国家知识产权局办公室、最高人民法院办公厅联合发布202...
联动解“薪愁”!新兴县综治中心... 近日,新兴县社会治安综合治理中心调解大厅内暖意融融,工人代表刘某某手持一面印着“解民薪忧办实事,勤政...
原创 中... 最近,巴拿马阿赖汉市政府做出了一个引人注目的决定:在未提前通知的情况下,夜间悄然拆除了中巴公园及其标...
(粤港澳大湾区)大湾区仲裁员及... 中新社香港12月30日电 记者30日从香港特区政府律政司获悉,粤港澳三地法律部门当日正式发布《粤港澳...
中央商场控股子公司被泗阳规划局... 观点网讯:12月30日,南京中央商场(集团)股份有限公司发布公告,披露其控股子公司泗阳雨润中央购物广...
涉嫌内幕交易!千亿锂矿巨头被移... 锂矿龙头之一的赣锋锂业突发公告。 12月29日晚间,江西赣锋锂业集团股份有限公司(以下简称“赣锋锂业...
中央商场控股子公司泗阳雨润被江... 观点网讯:12月30日,南京中央商场(集团)股份有限公司发布公告,披露其控股子公司泗阳雨润中央购物广...