当前位置: 首页 > news >正文

React函数组件Hook

问题: 相对于类组件, 函数组件的编码更简单, 效率也更高, 但函数组件不能有state (旧版)

解决: React 16.8版本设计了一套新的语法来让函数组件也可以有state

  • Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性

  • Hook也叫钩子,本质就是函数,能让你使用 React 组件的状态和生命周期函数...

  • Hook 语法 基本已经代替了类组件的语法

  • 后面的 React 项目就完全是用Hook语法了

Hook API 索引 – React 官方文档: Hook API 索引 – React

hook函数和普通函数的区别:

hook函数本身就是一个函数。react通过函数名来判断是普通函数还是hook函 数,以useXxx 格式命名的就是hook函数。

Hook函数使用原则:

1.不能在类组件中使用,不能在普通函数中使用

2.只能在函数组件中使用,或其他hook函数中使用【react提供的,第三方的,自定义的】

3..hook函数必须是数量确定的,不能写在逻辑判断中或后,不能写在循环中

4.应用时,一般写在顶级作用域的首行 使用场景

-----1.可以在函数组件中使用

let [msg, setMsg] = useState('')function clickHandler(){// let [count,setCount] = useState() // 普通函数会报错}

-----2.自定hook中可以使用其他hook

function useClickHandler(){let [count,setCount] = useState(0)}

-----3.如果函数名首字母大写,他会 认为是函数组件,也不会报错

 function ClickHandler(){let [count,setCount] = useState(0)}

1.useState()

作用:给函数组件添加状态

返回值:是一个数组,第一个元素是状态,第二个元素是设置状态的函数

语法:let [状态, 设置状态函数] = useState(初始值)

import React,{useState} from 'react'export default function App() {console.log('App render')let [count,setCount] = useState(0)return (<div><h3>App</h3><p>{count}</p><p><button onClick={()=>{setCount(1000)}}>count + 1</button></p></div>)
}

2.useEffect

作用:用来模拟函数组件的生命周期 componentDidMount、componentDidUpdate、ComponentWillUnmounted

2.1.用法:

useEffect(回调函数) : 没有第二个参数 模拟 componentDidMount + componentDidUpdate

useEffect(() => {console.log('useEffect') 
})
2.2.用法

useEffect(回调函数,[]) 只模拟 componentDidMount

 useEffect(()=>{console.log('useEffect')   // componentDidMount},[])
2.3.用法

useEffect(回调函数,[某 个自身状态(state) , 某个 外部状态(props), .......])

useEffect(() => { console.log('useEffect')}, [count])
2.4.用法

useEffect( return ()=>{ } )   模拟componentWillUnmount

useEffect(()=>{console.log('Test useEffect')return ()=>{ // componentWillUnmountconsole.log('destroy')}},[msg,money])

3.useRef

作用 :可以用它获取dom元素

1. 创建一个ref let divRef = useRef()

2. 绑定ref

3. 获取dom元素

import React, { useRef } from "react";
export default function App() {let divRef = useRef();return (<div><div ref={divRef}><h3>app</h3><button onClick={()=>{console.log(divRef.current);}}>获取DOM元素</button></div></div>);
}

4.useContext

作用 :获取从祖先组件传递给后代组件的数据

4.1.创建context对象

context.js 代码

import React from 'react'
// 1. 创建context对象,并暴露出去
const context = React.createContext() 
export default context
4.2.使用Provider组件包裹 组件, 并通过 value 绑定要传的数据

App.jsx 代码

import React from "react";
import Father from "./components/Father50";
import context from "./context";
export default function App() {return (// 2. 使用Provider包裹组件,并通过value绑定要传输的数据<context.Provider value={{ name: "App的内容" }}><div><h3>App</h3><hr /><Father /></div></context.Provider>);
}
4.3. 引入context对象
4.4.通过useContext处理context对象,获取祖先组件传递的数据
import React from 'react'// 3. 引入context对象
import context from '../context'
import { useContext } from "react";export default function Father() {// 4. 通过useContext处理context对象,获取祖先组件传递的数据let {name} = useContext(context)return (<div><h4>Father</h4><p>Father-context: {name}</p><hr /></div>)
}

5.useReducer

集中状态管理。相当于是简化版的 redux

import React, { useState } from 'react'
import { useReducer } from 'react'
const initalState = { count: 0, msg: 'atguigu' }
function reducer(state, action) {switch (action.type) {case 'inc':return {...state,count: state.count + 1}case 'dec':return {...state,count: state.count - 1}case 'add':return {...state,msg:state.msg + '+'}default:throw new Error('没有处理case')}
}
export default function App() {let [state, dispatch] = useReducer(reducer, initalState)return (<div><p>count: {state.count}</p><p>msg: {state.msg}</p><p><button onClick={()=>{dispatch({type:'inc'})}}>count + 1</button></p><p><button onClick={()=>{dispatch({type:'add'})}}>msg + '+'</button></p></div>)
}

6.useCallBack

可以缓存一个函数。避免函数的多次创建。性能优化

用法一:

没有第二个参数,函数仍然会被重复创建

  let clickHandler = useCallback(() => {setCount(count + 1);});

用法二:

第二个参数是空数组,那么函数会被缓存

    let clickHandler = useCallback(()=>{// setCount(count + 1)// 函数被缓存,可以使用setXxx 第二种用法,获取最新的状态值setCount(count=>count + 1)},[])

用法三:

第二个参数是数组,并监听 x 个 状态,当这些状态中的一个或多个发生变化时,重新创建函数

  let clickHandler = useCallback(() => {setCount(count + 1);// 函数被缓存,可以使用setXxx 第二种用法,获取最新的状态值// setCount(count=>count + 1)}, [count]);

7.React.memo

作用:类似于类组件中的纯组件。当自身状态和外部数据没有变化的时候,不会重新渲染

App.jsx 代码

import React, { Component } from 'react'
import Test from './components/Test56'
export default class App extends Component {state = {msg:'React'}render() {console.log('App render')return (<div><h3>App</h3><p>msg: {this.state.msg}</p><p><button onClick={()=>this.setState({msg:'React'})}>msg change</button></p><hr /><Test msg={this.state.msg}/></div>)}
}

 Test.jsx 代码

import React from 'react'
import { useState } from 'react'function Test({msg}) {console.log('Test render')// useState已经对自身状态做过优化let [count,setCount] = useState(0)return (<div><p>count:{count}</p><p>App-msg: {msg}</p><button onClick={()=>{setCount(100)}}>count + 1</button></div>)
}export default React.memo(Test)

如图所示:

8.useMemo

作用:缓存一个函数计算的结果,常用来跟useCallback进行比较;useCallback是缓存一个 函数,useMemo缓存函数执行的结果

通俗来讲就是:它是一个优化性能的 Hook,它会记住函数的返回值,只要依赖项(dependency array)没有变化,就会复用之前的计算结果,避免在每次渲染时都重新执行这个可能开销较大的计算

官方详解:

App.jsx 代码

import React from 'react'
import Test from './components/Test57'export default function App() {return (<div><Test/></div>)
}

Tset.jsx 代码

import React, { useState,useMemo } from 'react';export default function Test() {
const [count,setCount] = useState(0)
const [val,setVal] = useState(0)const expensive = useMemo(()=>{console.log('================');let sum =0for(let i=1;i<count;i++){sum += i}return sum
},[count])// const expensive = (()=>{
//     console.log('================');
// },[count])return <div><h4>{count}-{val}-{expensive}</h4><div><button onClick={()=>setCount(count + 1)}>+c1</button><input val={val} onChange={event =>{setVal(event.target.value)}}/></div></div>;
}

9.useImperativeHandle

它与 forwardRef 结合使用以暴露自定义组件的 refs 给父组件。可以在使用 `ref` 时自定义暴露给父组件的实例值

官方文档:useImperativeHandle – React

APP.jsx 代码

import React from 'react'
import { useRef } from 'react'
import FunTest from './components/FunTest58'export default function App() {// ref可以给绑定类组件,并且可以获取类组件实例对象let refClass = useRef()// ref本身不能够给函数组件使用,但是可以通过 React.forwardRef()进行扩展let refFn = useRef('true')/*** 当希望在父组件获取子组件的dom对象的时候,可以使用 函数组件配合 React.forwardRef()实现*/return (<div><FunTest ref={refFn} /><p><button onClick={() => {console.log(refClass)console.log(refFn)}}>获取ref</button></p><p><button onClick={() => {refFn.current.changeBg()}}>changeBg</button></p><p><button onClick={() => {refFn.current.changeFontSize()}}>changeBg</button></p></div>)
}

FunTest.jsx 代码

import React from "react";
import { useRef, useImperativeHandle } from "react";function FunTest(props, AppRef) {let selRef = useRef()useImperativeHandle(AppRef,()=>({changeBg:()=>{selRef.current.style.backgroundColor = "red"}}))return (<div><h3 ref={selRef}>FunTest</h3></div>);
}
export default React.forwardRef(FunTest);

 如图所示:

10.useLayoutEffect

useLayoutEffect是useEffect的一个版本,在浏览器重新绘制屏幕之前触发。

useEffect在render结束后,你的callback函数执行,但是不会阻塞浏览器渲染

作用:用在处理DOM的时候,当你的useEffect里面的操作需要处理DOM,并且会改变页面的样式,就需要用这个,否 则可能会出现出现闪屏问题, useLayoutEffect里面的callback函数会在DOM更新完成后立即执行,但是会在 浏览器进行任何绘制之前运行完成,阻塞了浏览器的绘制

官方文档:useLayoutEffect – React

App.jsx 代码

import React from 'react'
import Animate from './components/Animate59'export default function App() {return (<div><Animate/></div>)
}

Animate.jsx 代码

import React, { useEffect, useLayoutEffect, useRef } from 'react'
import TweenMax from 'gsap' // npm i gsap@3.7.0
import '../index.css'const Animate = () => {const REl = useRef(null)useLayoutEffect(()=>{TweenMax.to(REl.current,0,{x:600})},[])return (<div className="animate"><div ref={REl} className="square">square</div></div>)
}
export default Animate

11.useDebugValue

作用:用于在 React 开发者工具中显示 自定义 hook 的标签,只能在自定义hook中使用

官方文档:useDebugValue – React

12.useId

用于生成一个唯一的标识

import React from 'react'
import { useId } from 'react'export default function App() {let id1 = useId()let id2 = useId()console.log(id1);console.log(id2);return (<div><div>App</div></div>)
}

 

13.useTransition

作用:可以将任务设置为非紧急任务

官方文档:useTransition – React

const [isPending, startTransition] = useTransition()
startTransition(()=>{})

14.useDeferredValue

作用:根据一个状态,设置一个延时的状态。也可以实现,任务渲染的优先级区别

import { useState, useDeferredValue } from 'react';function SearchPage() {const [query, setQuery] = useState('');const deferredQuery = useDeferredValue(query);// ...
}

15.自定义hook函数

作用: 函数组件代码逻辑复用的手段,函数名 useXxx 格式 ,函数中可以使用其他hook函数

App.jsx 代码

import React, {useState} from 'react'
import { useEffect } from 'react'
import usePosition from '../hook/usePosition'
export default function Cat() {let {x,y} = usePosition()return (<div style={{width:100,height:100,border:'1px solid red',position:'absolute',left:x,top:y}}>Cat</div>)
}

 usePosition.js 代码

import {useState, useEffect} from 'react'
export default function usePosition() {let [x, setX] = useState(0)let [y, setY] = useState(0)function moveHandler(e) {setX(e.clientX)setY(e.clientY)}useEffect(() => {window.addEventListener('mousemove', moveHandler)return () => {window.removeEventListener('mousemove', moveHandler)}}, [])return {x,y}
}

相关文章:

React函数组件Hook

问题: 相对于类组件, 函数组件的编码更简单, 效率也更高, 但函数组件不能有state (旧版) 解决: React 16.8版本设计了一套新的语法来让函数组件也可以有state Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性 Hook也叫钩子…...

【FinalShell】远程连接 Linux 工具 FinalShell 的使用:查看 AI 语言大模型对话实时日志

一、查看 APP 实时 AI 问答消息的 websocket 类型日志 &#xff08;1&#xff09;Linux 模板命令配置 Linux 命令&#xff1a;查看 AI 语言大模型结合向量数据库的实时问答消息日志 ① 测试环境 FinalShell 命令模板 【Linux 命令标题】[Test_APP] today tail&#xff1a;webs…...

ARM Coresight 系列文章 11.1 -- CoreSight Cortex-M33 CTI 详细介绍】

请阅读【ARM Coresight SoC-400/SoC-600 专栏导读】 文章目录 CTI 的工作原理CTI 主要特点CTI的使用场景CTI 的工作原理 CTI 允许不同的调试和追踪组件之间基于特定事件进行交互。例如,当一个断点被命中时,CTI 可以用来触发内存的追踪捕捉或者外部仪器的行为,反之亦然。这种…...

Linux常用操作命令(清单快查版)

Linux常用操作命令&#xff0c;今日先给出快查清单&#xff0c;后续出带命令参数及不同OS的区别语法的相关示例 1. 文件与目录操作 命令描述ls列出目录内容cd切换目录pwd显示当前工作目录mkdir创建目录rmdir删除空目录cp复制文件或目录mv移动或重命名文件或目录rm删除文件或目…...

[C语言]结构体、位段、枚举常量、联合体

目录 结构体 结构体的使用方法 结构体所占用的大小 位段 位段的使用方法 位段所占用的大小 枚举常量 枚举常量的使用方法 枚举常量的优势 联合体 联合体的使用方法 结构体 结构体的使用方法 结构体是一些值的集合&#xff0c;我们可以定义一个结构体&#xff0c;里…...

LangChain核心模块 Retrieval——文档加载器

Retrieval ​ 许多LLM申请需要用户的特定数据&#xff0c;这些数据不属于模型训练集的一部分&#xff0c;实现这一目标的主要方法是RAG(检索增强生成)&#xff0c;在这个过程中&#xff0c;将检索外部数据&#xff0c;然后在执行生成步骤时将其传递给LLM。 ​ LangChain 提供…...

力扣爆刷第104天之CodeTop100五连刷6-10

力扣爆刷第104天之CodeTop100五连刷6-10 文章目录 力扣爆刷第104天之CodeTop100五连刷6-10一、15. 三数之和二、53. 最大子数组和三、912. 排序数组四、21. 合并两个有序链表五、1. 两数之和 一、15. 三数之和 题目链接&#xff1a;https://leetcode.cn/problems/3sum/descrip…...

Docker操作基础命令

注意&#xff1a;以下命令在特权模式下进行会更有效&#xff01; 进入特权模式 sudo -ssudo su拉取镜像 sudo docker pull [镜像名] # sudo docker pull baiduxlab/sgx-rust:2004-1.1.3进入容器 端口开启服务&#xff1a; sudo docker start 3df9bf5dbd0c进入容器&#xf…...

穿越地心:3D可视化技术带你领略地球内部奇观

在广袤无垠的宇宙中&#xff0c;地球是一颗充满生机与奥秘的蓝色星球。我们每天都生活在这颗星球上&#xff0c;感受着它的温暖与恩赐&#xff0c;却往往忽略了它深邃的内部世界。 想象一下&#xff0c;你能够穿越时空&#xff0c;深入地球的核心&#xff0c;亲眼目睹那些亿万年…...

蓝桥杯刷题_day1_回文数_水仙花数_进制转换

文章目录 特殊的回文数回文数水仙花数十六进制转八进制_n次 特殊的回文数 问题描述   123321是一个非常特殊的数&#xff0c;它从左边读和从右边读是一样的。   输入一个正整数n&#xff0c; 编程求所有这样的五位和六位十进制数&#xff0c;满足各位数字之和等于n 。 解题…...

jmeter接口导入方式

curl直接导入 1、操作页面后&#xff0c;F12查看接口&#xff0c;右击接口-copy-copy as cURL 2、jmeter 工具-import from cURL&#xff0c;粘贴上面复制的curl 根据接口文档导入 1、接口文档示例如下&#xff1a; Path&#xff1a; /api/jobs/xps/exec Method&#xf…...

设计模式(行为型设计模式——状态模式)

设计模式&#xff08;行为型设计模式——状态模式&#xff09; 状态模式 基本定义 对有状态的对象&#xff0c;把复杂的“判断逻辑”提取到不同的状态对象中&#xff0c;允许状态对象在其内部状态发生改变时改变其行为。 模式结构 Context&#xff08;环境类&#xff09;&…...

【Flutter学习笔记】10.3 组合实例:TurnBox

参考资料&#xff1a;《Flutter实战第二版》 10.3 组合实例&#xff1a;TurnBox 这里尝试实现一个更为复杂的例子&#xff0c;其能够旋转子组件。Flutter中的RotatedBox可以旋转子组件&#xff0c;但是它有两个缺点&#xff1a; 一是只能将其子节点以90度的倍数旋转二是当旋转…...

性能测试入门 —— 什么是性能测试PTS?

性能测试PTS&#xff08;Performance Testing Service&#xff09;是一款简单易用&#xff0c;具备强大的分布式压测能力的SaaS压测平台。 PTS可以模拟复杂的业务场景&#xff0c;并快速精准地调度不同规模的流量&#xff0c;同时提供压测过程中多维度的监控指标和日志记录。您…...

【机器学习】基于变色龙算法优化的BP神经网络分类预测(SSA-BP)

目录 1.原理与思路2.设计与实现3.结果预测4.代码获取 1.原理与思路 【智能算法应用】智能算法优化BP神经网络思路【智能算法】变色龙优化算法&#xff08;CSA)原理及实现 2.设计与实现 数据集&#xff1a; 数据集样本总数2000 多输入多输出&#xff1a;样本特征24&#xff…...

pytorch中tensor类型转换的几个函数

目录 IntTensor转FloatTensor FloatTensor转IntTensor Tensor类型变为python的常规类型 IntTensor转FloatTensor .float函数&#xff1a; FloatTensor转IntTensor .int函数 Tensor类型变为python的常规类型 item函数...

深入理解Elasticsearch高效原理

在当今数据驱动的世界中&#xff0c;能够快速有效地存储、搜索和分析庞大数据集变得至关重要。Elasticsearch是一个强大的开源搜索和分析引擎&#xff0c;专为云计算中心而设计&#xff0c;能够提供快速的搜索功能&#xff0c;并且能够扩展到包含数百个服务器的集群&#xff0c…...

http和socks5代理哪个隐蔽性更强?

HTTP代理和SOCKS5代理各有其优缺点&#xff0c;但就隐蔽性而言&#xff0c;SOCKS5代理通常比HTTP代理更隐蔽。以下是它们的比较&#xff1a; HTTP代理&#xff1a; 透明性较高&#xff1a;HTTP代理在HTTP头中会透露原始客户端的IP地址&#xff0c;这使得它相对不太隐蔽。…...

邮箱的正则表达式

一、 背景 项目中要给用户发送邮件&#xff0c;这时候需要校验用户输入的邮箱的有有效性&#xff0c;这肯定用正则呀。 虽然没有统一的邮箱账号格式&#xff0c;但是所有邮箱都符合“名称域名”的规律。对于名称和域名的字符限制&#xff0c;我们可以根据项目的情况定义一个&a…...

blender插件笔记

目录 文件拖拽导入 smpl导入导出 好像可以导入动画 smpl_blender_addon导入一帧 保存pose 导入导出完整代码 文件拖拽导入 https://github.com/mika-f/blender-drag-and-drop 支持格式&#xff1a; *.abc*.bvh*.dae*.fbx*.glb*.gltf*.obj*.ply*.stl*.svg*.usd*.usda*.…...

【Oracle APEX开发小技巧12】

有如下需求&#xff1a; 有一个问题反馈页面&#xff0c;要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据&#xff0c;方便管理员及时处理反馈。 我的方法&#xff1a;直接将逻辑写在SQL中&#xff0c;这样可以直接在页面展示 完整代码&#xff1a; SELECTSF.FE…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:

一、属性动画概述NETX 作用&#xff1a;实现组件通用属性的渐变过渡效果&#xff0c;提升用户体验。支持属性&#xff1a;width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项&#xff1a; 布局类属性&#xff08;如宽高&#xff09;变化时&#…...

前端倒计时误差!

提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

线程同步:确保多线程程序的安全与高效!

全文目录&#xff1a; 开篇语前序前言第一部分&#xff1a;线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分&#xff1a;synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分&#xff…...

Docker 运行 Kafka 带 SASL 认证教程

Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明&#xff1a;server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

2024年赣州旅游投资集团社会招聘笔试真

2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

JVM垃圾回收机制全解析

Java虚拟机&#xff08;JVM&#xff09;中的垃圾收集器&#xff08;Garbage Collector&#xff0c;简称GC&#xff09;是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象&#xff0c;从而释放内存空间&#xff0c;避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

【机器视觉】单目测距——运动结构恢复

ps&#xff1a;图是随便找的&#xff0c;为了凑个封面 前言 在前面对光流法进行进一步改进&#xff0c;希望将2D光流推广至3D场景流时&#xff0c;发现2D转3D过程中存在尺度歧义问题&#xff0c;需要补全摄像头拍摄图像中缺失的深度信息&#xff0c;否则解空间不收敛&#xf…...

学校招生小程序源码介绍

基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码&#xff0c;专为学校招生场景量身打造&#xff0c;功能实用且操作便捷。 从技术架构来看&#xff0c;ThinkPHP提供稳定可靠的后台服务&#xff0c;FastAdmin加速开发流程&#xff0c;UniApp则保障小程序在多端有良好的兼…...

深度学习习题2

1.如果增加神经网络的宽度&#xff0c;精确度会增加到一个特定阈值后&#xff0c;便开始降低。造成这一现象的可能原因是什么&#xff1f; A、即使增加卷积核的数量&#xff0c;只有少部分的核会被用作预测 B、当卷积核数量增加时&#xff0c;神经网络的预测能力会降低 C、当卷…...