react 函数式组件的hooks

news2025/1/16 8:20:18

目录

useState

useEffect

useCallback

useMemo

useRef

useContext

useReducer

自定义hooks


useState

函数式组件的状态 ,格式: const [value,setValue] = useState( {xxxx} )

console.log([value, setValue])打印一下可以看到:

  • value-----状态变量名称
  • setValue-----与变量相对应的一个更改状态值的方法
  • {xxxx} -----状态的初始值,对象、数组、函数、字符串等都可以

简单使用示例:

import './App.css';

import React, {useState} from 'react'


export default function App() {

  const [value, setValue] = useState({id:0,name:'蔡某坤'})

  console.log([value, setValue])
  return (
    <div>
        <button onClick={()=>setValue({id:1,name:'英雄可以受委屈,但你不能踩我的切尔西'})}>改变</button>
        <div>{value.name}</div>
    </div>
  )
}


useEffect / useLayoutEffect

  useEffect(() => {
    console.log("我被执行了")
    //setValue({id:1,name:'英雄可以受委屈,但你不能踩我的切尔西'})
    return ()=>{}
  },[value]);
  •  useEffect

        useEffect相当于componentDidMount、componentDidUpdate、componentWillUnmount的合并。在一开始的时候会默认执行两遍,后续每次重新渲染时会调用一次:

         此方法有第二个参数,第二个参数为useState变量的依赖。不加第二个参数就是普通的componentDidMount + componentDidUpdate; 加了第二个参数则表示对指定状态进行监听,只有被指定的状态发生改变时才会执行,类似于Vue的watch、computed,需要注意的是,如果加了第二个参数就不能在此方法内对指定状态的修改,否则会造成死循环。

        回调函数用于清空一些事件监听:

import './App.css';
import React, {useState,useEffect} from 'react'

export default function App() {

  const [value, setValue] = useState(true)

  return (
    <div>
        <button onClick={()=>setValue(!value)}>改变</button>
        {value? <A/>:'子组件已被销毁'}
    </div>
  )
}

function A() {
  
  const [value, setValue] = useState(0)

  useEffect(() => {
    var times=setInterval(() => {
      console.log("英雄可以受委屈,但你不能踩我的切尔西")
      setValue(value+1)
    }, 1000);
    return ()=>{clearInterval(times)}
  });

  return (
    <div>
        <div>我是子组件{value}</div>
    </div>
  )
}
  • useLayoutEffect

useLayoutEffect 和 useEffect的区别在于调用的时机不同,useLayoutEffect是在DOM更新完成后,页面渲染之前调用的,useEffect则是在页面完成渲染后执行的。同样的,componentDidMount 和componentDidUpdate也是在DOM更新完成后,页面渲染之前调用的,使用useLayoutEffect可能会造成页面的阻塞,而useEffect则可能会造成页面抖动。


useCallback

         useCallback(记忆函数)。当setCount触发时,会将整个函数内所有东西都进行重新执行,内部的方法自然而然地也会被重新定义,此时使用useCallback可以有效地减少函数的创建,重新渲染时并不会去执行它。

        useCallback有两个参数,第一个参数为方法,第二个参数为[ xxx ],其中xxx为定义的状态名称。当第二个参数不填或者为空数组时,其内部的值是不变的,永远都是上一次初始化缓存下来的值;当填入相关的副作用,如下面例子的 [ ] 替换成 [ count ] 时,当count这个值发生改变时,useState会自动缓存下此次更新的值,有些许类似Vue中的计算属性。

import React, { useCallback, useState } from 'react'

export default function App() {

  const [count, setCount] = useState(0);

  const add =useCallback( () => {
    setCount(count + 1)
  },[])

  return (
    <div>
      <button onClick={() => { add() }}>增加</button>
      {count}
    </div>
  )
}

useMemo

        useMemo与useCallback 相类似:useCallback返回你传入的函数,useMemo返回一个值;useCallback传入的方法不会自动执行,useMemo传入的方法会自动执行。

import React, { useMemo, useState } from 'react'

export default function App() {

  const [count, setCount] = useState(0);

  const add =useMemo( () => {
    console.log("我被执行了")

    return count
  },[count])   

  return (
    <div>
      <button onClick={() => { setCount(add + 1) }}>增加</button>
      {count}
      <hr></hr>
      <div>add方法自动返回:{add}</div>
    </div>
  )
}


 

useRef

跟类组件的ref一样,通过绑定获取DOM节点。

import React, { useMemo, useRef, useState } from 'react'

export default function App() {

  const [text, setText] = useState("");

  const input_ref=useRef();

  return (
    <div>
      <input ref={input_ref} onChange={()=>setText(input_ref.current.value)}></input>
      <div>输入框的值:{text}</div>
    </div>
  )
}

 

 


useContext

函数式组件的提供者与消费者,示例如下:

import React, { useContext, useRef, useState } from 'react'

const context = React.createContext()

export default function App() {

  const [text,setText]=useState("")
  const input_ref=useRef()

  return (
    <div>
      <context.Provider value={text}>
        <div>我是父组件:{text}</div>
        <input ref={input_ref} onChange={() => setText(input_ref.current.value)}></input>
        <A/>
      </context.Provider>
    </div>
  )
}

function A() {

  const A_context = useContext(context)

  return (
    <div>
      <hr></hr>
      <div>我是子组件,用context接收到的值:{A_context}</div>
      <hr></hr>
    </div>
  )
}

 


 

useReducer

        useReducer 全局状态管理。useState的替代方案。它接收一个形如 (state, action) => newState 的 reducer,并返回当前的 state 以及与其配套的 dispatch 方法,类似于类组件的订阅发布,

import React ,{useReducer}from 'react'

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return {count: state.count + 1};
    case 'decrement':
      return {count: state.count - 1};
    case 'reset':
      return {count: action.payload};
    default:
      throw new Error();
  }
}

 export default function App() {
  const [state, dispatch] = useReducer(reducer, {count:0});
  return (
    <>
      Count: {state.count}
      <button
        onClick={() => dispatch({type: 'reset', payload: 0})}>
        Reset
      </button>
      <button onClick={() => dispatch({type: 'decrement'})}>-</button>
      <button onClick={() => dispatch({type: 'increment'})}>+</button>
    </>
  );
}

自定义hooks

在函数式组件内使用自定义的指令,需要以use开头。

如下,我将其分割出去了两个方法: 

import React, {  useRef, useState } from 'react'

export default function App() {

  const [text,setText]=useState("")
  const input_ref=useRef()

  const input_change=()=>{
      setText(input_ref.current.value)
  }

  const input_text=()=>{
    return "【"+text+"】"
  }

  return (
    <div>
        <div>input的值:{input_text()}</div>
        <input ref={input_ref} onChange={input_change}></input>
    </div>
  )
}

 将这两个方法移动外部,函数名以“use”开头命名,然后在组件内就可以进行使用了,自定义hooks可以将组件内的方法移到外部,增加代码的直观性。

import React, { useRef, useState } from 'react'

export default function App() {

  const [text, setText] = useState("")
  const input_ref = useRef()

  const input_change = useInputChange(setText, input_ref)

  const input_text = useInputText(text)

  return (
    <div>
      <div>input的值:{input_text}</div>
      <input ref={input_ref} onChange={input_change}></input>
    </div>
  )
}

function useInputChange(setText, input_ref){
    return ()=>setText(input_ref.current.value)
}


function useInputText(text) {
  return "【"+text+"】"
}


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/379031.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

腾讯安全与锐捷网络战略合作,威胁情报能力“被集成”

2月28日&#xff0c;腾讯安全和锐捷网络在北京联合举办“威胁情报”战略合作发布会。双方发布了一款集成了腾讯安全威胁情报的新一代防火墙&#xff0c;并举办战略合作签约仪式。会上&#xff0c;锐捷网络安全产品事业部总经理项小升、腾讯安全总经理陈龙代表双方签署战略合作协…

taobao.user.avatar.get

&#xffe5;开放平台基础API不需用户授权 根据混淆nick查询用户头像 公共参数 请求地址: HTTP地址 http://gw.api.taobao.com/router/rest 公共请求参数: 公共响应参数: 点击获取key和secret 请求参数 请求示例 TaobaoClient client new DefaultTaobaoClient(url, appkey,…

MyBatis中#{}和${}的区别

目录 前言 1、处理参数的方式不同 2、${}的优点 3、SQL注入问题 4、like查询问题 前言 #{}和${}都可以在MyBatis中用来动态地接收参数&#xff0c;但二者在本质上还是有很大的区别。 1、处理参数的方式不同 ${} &#xff1a;预编译处理 MyBatis在处理#{}时&#xff0c…

【Android】全局加载框的使用

项目需求 在网络加载中使用网络加载框&#xff0c;在请求数据或者其他耗时操作的时候&#xff0c;显示加载框&#xff0c;当数据返回之后或者操作完成的时候加载框取消。 效果如下&#xff1a; 需求实现 使用一个开源库【Gloading】实现 项目地址链接: Gloading 1.引入依赖…

umi 中如何使用 px2rem 插件做rem适配

umi 中如何使用 px2rem 插件做rem适配在umi的src下面创建两个文件app.ts和document.ejs下载lib-flexible和postcss-px2rem-exclude在.umirc.ts文件中进行配置和postcss-px2rem-exclude的引入在app.ts文件中引入lib-flexible如果px2rem配置无法生效&#xff0c;那么我们就要在do…

Javascript的API基本内容(五)

一、js组成 JavaScript的组成 ECMAScript: 规定了js基础语法核心知识。 比如&#xff1a;变量、分支语句、循环语句、对象等等 Web APIs : DOM 文档对象模型&#xff0c; 定义了一套操作HTML文档的API BOM 浏览器对象模型&#xff0c;定义了一套操作浏览器窗口的API 二、loc…

JavaScript从零开始 学习记录(二)

前言 寒假花了大气力去整理公众号&#xff0c;因而一些任务没有完成&#xff0c;但没有关系&#xff0c;毕竟计划赶不上变化&#xff0c;接着学习&#xff0c;争取早日开发油猴脚本 笔记范围 从这节视频到那节视频结束 课程目标 能够知道为什么要有数组能够创建数组能够获…

“来源可靠、程序规范、要素合规”与“四性”

《从技术可行性的视角看电子档案的“四性”》一文中已经明确&#xff0c;笔者认为的电子档案“四性”是指“真实性、完整性、可用性和安全性”。而《从特斯拉“刹车失灵”事件看电子档案的法定要求》一文中&#xff0c;笔者对于“来源可靠、程序规范、要素合规”的解读如下&…

Qt基础之三十:百万级任务并发处理

在实际的开发过程中,经常会遇到要处理大量任务场景,比如说压缩文件夹中的所有文件、对文件夹中的所有文件加密、上传文件夹中的所有文件到ftp等等。这里说百万级并不夸张,理论上文件夹中有任意多个文件都是可以的。 本文以压缩文件夹中的100万张jpg图片为例,压缩工具使用的…

外卖扫码点餐系统源码 后台管理端+商家端+门店端+小程序用户端源码

外卖点餐 堂食点餐 扫码点餐 本套扫码点餐系统源码基于java语言开发&#xff0c;移动端原生小程序&#xff0c;SaaS模式。代码完整&#xff0c;带部署调试视频。 系统由总后台管理端商家端门店端小程序用户端组成&#xff0c;支持扫码点单、计费结账、出菜上菜、菜品管理、菜…

【办公类-19-02】办公中的思考——Python批量制作word文本框的名字小标签,用A4word打印(植物角、家长会、值日生)

背景需求&#xff1a; 2月28日去小班带班&#xff0c;看到班主任制作了一些小手印花束作为家长会的家长座位提示&#xff0c;上面贴着“”圆形白色的幼儿名字贴”。 我立刻想起了制作的过程——在word中插入文本框&#xff0c;然后复制无数个文本框&#xff0c;摆好位置&#…

【AI绘画】绝美春天插画,人人都是插画师

春天&#xff0c;自然界重新苏醒&#xff0c;生机勃勃&#xff0c;百花争艳&#xff0c;万籁俱寂。一切都被新的生命活力所染上。春风拂面&#xff0c;一股清新的空气流过&#xff0c;仿佛带着一种神秘的力量&#xff0c;让人心旷神怡&#xff0c;心情舒畅、轻松愉悦。 突然&a…

549、RocketMQ详细入门教程系列 -【消息队列之 RocketMQ(三)】 2023.02.28

目录一、Spring 整合 RocketMQ1.1 消息生产者1.2 消息消费者1.3 Spring 配置文件1.4 运行实例程序二、参考链接一、Spring 整合 RocketMQ 不同于 RabbitMQ、ActiveMQ、Kafka 等消息中间件&#xff0c;Spring 社区已经通过多种方式提供了对这些中间件产品集成&#xff0c;例如通…

WebRTC Opus编码器的创建与参数细节分析( sdp -> native )

这几天在做一些WebRTC音频改进方面的调查工作&#xff0c;在阅读Chromium源码的过程中&#xff0c;就顺便记录下来&#xff0c;便于日后回顾。本文基于Chromium 85源码分析&#xff0c;由于Chromium的快速发展&#xff0c;很有可能不适合于跨度太大的Chromium版本。大家知道Opu…

QT学习14:QtXlsx操作Excel表

一、前言操作excel方式有&#xff1a;QAxObject 和QtXlsx区别&#xff1a;Qt自带的QAxObject库操作excel的前提是电脑已经安装微软的Office&#xff08;包含EXCEL&#xff09;&#xff0c;而QtXlsx可以直接使用免装Office且操作更简单。二、QtXlsx操作示例参考&#xff1a;http…

C筑基——深入理解内存对齐

目录1 前言2 正文2.1 为什么要有内存对齐&#xff1f;2.2 内存对齐原则2.2.1 基本数据类型是自然对齐的2.2.2 包含基本数据类型成员的结构体套用结构体内存对齐原则来分析使用 gdb 查看这两个结构体的成员内存位置结构体类型变量是自然对齐的吗&#xff1f;2.2.3 数组类型2.3 修…

今天 4 点,龙蜥自动化运维平台SysOM 2.0的诊断中心功能介绍 | 第 66-68 期

本周 3 期「龙蜥大讲堂」预告来啦&#xff01;我们邀请了系统运维 SIG Contributor 阙建明分享《SysOM 2.0 诊断中心功能介绍》&#xff0c;龙蜥社区云原生机密计算 SIG Maintainer、Intel 高级云计算软件工程师黄晓军分享《Intel HE Toolkit 介绍》主题演讲&#xff0c;龙蜥社…

【Linux】操作系统与Linux — Linux概述、组成及目录结构

目录 一、什么是操作系统&#xff1f;都有那些&#xff1f; 二、Linux概述 三、Linux组成 三、Linux目录结构 四、Linux目录结构 &#x1f49f; 创作不易&#xff0c;不妨点赞&#x1f49a;评论❤️收藏&#x1f499;一下 一、什么是操作系统&#xff1f;都有那些&#x…

频率信号转电压或电流信号隔离变送器0-1KHz /0-5KHz /0-10KHz转0-2.5V/0-5V/0-20mA

主要特性:>> 精度等级&#xff1a;0.2级>> 全量程内极高的线性度&#xff08;非线性度<0.1%&#xff09; >> 辅助电源/信号输入/信号输出&#xff1a; 2500VDC 三隔离>> 辅助电源&#xff1a;5VDC&#xff0c;12VDC&#xff0c;24VDC等单电源供电&g…

2020蓝桥杯真题约数个数(填空题) C语言/C++

题目描述 本题为填空题&#xff0c;只需要算出结果后&#xff0c;在代码中使用输出语句将所填结果输出即可。 1200000 有多少个约数&#xff08;只计算正约数&#xff09;。 运行限制 最大运行时间&#xff1a;1s 最大运行内存: 128M 所需变量 int a 1200000;//初始最大数 i…