React + 项目(从基础到实战) -- 第三期

react内置hooks

useState

如何让页面动起来(实时更新)

import React,{FC,useState} from "react";const Demo:FC=()=>{let count=0; //普通js变量无法触发组件更新function add(){count++;console.log("count: ",count);}return <div><button onClick={add}>add {count}</button></div>}export default Demo;

在这里插入图片描述

为什么采用

state的改变可以触发函数组件的更新
(如果js变量不在jsx中使用,别用useState)

import React,{FC,useState} from "react";const Demo:FC=()=>{//    let count=0; //普通js变量无法触发组件更新const[count,setCount]=useState(0); //useState 可以触发组件更新function add(){// count++;setCount(count+1)console.log("count: ",count);}return <div><button onClick={add}>add {count}</button></div>}export default Demo;

在这里插入图片描述

特点

  1. 不可变数据
    不修改原数据,而是传入新的值

  2. 异步更新|
    函数中无法直接获取最新的值
    在这里插入图片描述

  3. 可能被合并
    使用函数state可以解决这个问题

在这里插入图片描述

 setCount(()=>{return count+5})

immer

是一个插件
解决state不可变数据的影响
安装 npm install -D immer

 import {FC,useState} from "react";import {produce} from "immer";const Demo : FC =()=>{const [list,setList]=useState(['x','y'])function add(){// setList(list.concat('z'));setList(produce(draft=>{draft.push('z')//直接在原数组上修改}))}return (<div><h2>state 不可变数据</h2><div>{JSON.stringify(list)}</div><button onClick={add}>add  item</button></div>)}export default  Demo;

useEffect

为什么

组件是一个函数,返回的是JSX片段,
组件初次渲染完成,即函数执行完成,
一般情况下函数执行完成就结束了
但是在state更新时,会触发组件更新,函数组件再次执行

为了解决以上问题,使用useEffect

import {FC,useEffect,useState} from "react"const Demo:FC=()=>{useEffect(()=>{console.log("组件初次渲染完成");return ()=>{console.log("组件销毁时执行");}},[])//无依赖项,只执行一次const[count,setCount]=useState(0); //useState 可以触发组件更新function add(){// count++;setCount(()=>{return count+5})console.log("count: ",count);}return <div><button onClick={add}>add {count}</button></div>}export default Demo;

注意

发现useEffect 执行两次

在react 18 中,useEffect 在开发环境中执行两次,在生产环境中执行一次
(模拟组件生命周期,以便尽早暴露问题)
开发环境 npm run build 生存环境

useRef

  1. 操作DOM
  2. 可传入普通js变量,但是更新不会触发rerender

与vue3 ref 不同

  import { FC,useRef } from "react";const Demo:FC = () => {// 定义一个refconst inputRef = useRef<HTMLInputElement>(null) //dom节点const nameRef=useRef("pink") //不是dom节点,是一个普通的js变量function selectInput(){const input = inputRef.current;if(input){input.select(); // 选中输入框中的内容(Dom节点操作API)}}function changeName(){nameRef.current="blue"//修改ref的值,不引起rerender(state修改会触发组件更新)console.log(nameRef.current);}return (<><input ref={inputRef} defaultValue={"hello world"}/><button onClick={selectInput}>选中 input</button><p>{nameRef.current}</p><button onClick={changeName}>修改名字</button></>)}export default Demo;

在这里插入图片描述

useMemo

缓存数据
不用每次执行函数组件(比如说 state修改)都重新生成 , 实现性能优化

import {FC,useMemo,useState} from "react"const Demo : FC =()=>{const[num1,setNum1]=useState(0)const[num2,setNum2]=useState(0)const[text,setText]=useState("hello") //更新导致组件rerenderconst sum =useMemo(()=>{console.log("计算两数之和");//缓存return num1+num2;},[num1,num2])return (<><p>sum = {sum}</p><button onClick={()=>{setNum1(num1+1)}}>num1 : {num1}</button><button onClick={()=>{setNum2(num2+1)}}>num2 : {num2}</button><button onClick={()=>{setText(text+"1")}}>text : {text}</button></>)}export default Demo;

在这里插入图片描述

useCallback

缓存函数

import {FC,useCallback,useState} from "react"const Demo : FC =()=>{const [text,setText] = useState("hello")const fn1=()=>{console.log("fn1 text",text);}const fn2=useCallback(()=>{console.log("fn2 text",text);},[text])return(<><button onClick={fn1}>fn1</button><button onClick={fn2}>fn2</button><div><input value={text} onChange={e=>setText(e.target.value)}></input></div></>)}export default Demo;

自定义hooks

抽离公共部分,复用代码

同步案例

监听鼠标位置

  1. 自定义hook
import { useState,useEffect } from "react";//获取鼠标位置function useMouse(){const [x,setX]=useState(0);const [y,setY]=useState(0);const mouseMoveHandler=(e:MouseEvent)=>{setX(e.clientX);setY(e.clientY);}useEffect(()=>{//监听鼠标事件window.addEventListener('mousemove',mouseMoveHandler);//组件销毁时,一定要解绑DOM事件!!(可能会导致内存泄漏问题)return ()=>{window.removeEventListener('mousemove',mouseMoveHandler);}},[])return {x,y}}export default useMouse;
  1. app.tsx 中引入
//导入自定义hookimport useMouse from "./hooks/useMouse.ts";function App() {const {x, y} = useMouse();return(<><p>App Page</p><div>x: {x}</div><div>y: {y}</div></>)}export default App

异步案例

模拟加载效果

import { useState,useEffect } from "react";//异步获取消息function getInfo():Promise<string>{return new Promise(resolve=>{setTimeout(()=>{resolve(Date.now().toString())  },1500)})}//自定义钩子const useGetInfo=()=>{const[loading,setLoading]=useState(true)const[info,setInfo]=useState("")useEffect(()=>{getInfo().then(info=>{setLoading(false)setInfo(info)})},[])return {loading,info}}export default useGetInfo;

第三方hooks

提高开发效率

ahooks

react-hooks

hooks使用规则

  1. useXxx命名
  2. 组件内 获 其他hook 中可以调用
  3. 保证每次调用顺序一致(不能处于 if/for 内部)

面试题(闭包陷阱)

无法获取最新值

import {FC,useState} from 'react'const Demo:FC =()=>{const[count,setCount]=useState(0)function add(){setCount(count+1)}function alertFn(){setTimeout(()=>{alert(count);},3000)}return(<><p>闭包陷阱</p><div><span>{count}</span><button onClick={add}>add</button><button onClick={alertFn}>alert</button></div></>)}export default Demo;

使用ref解决在这里插入图片描述

import {FC,useState,useRef, useEffect} from 'react'const Demo:FC =()=>{const[count,setCount]=useState(0)const countRef = useRef(0)function add(){setCount(count+1)}useEffect(()=>{countRef.current=count},[count])function alertFn(){setTimeout(()=>{// alert(count); //count 值类型alert(countRef.current); // ref 引用类型},3000)}return(<><p>闭包陷阱</p><div><span>{count}</span><button onClick={add}>add</button><button onClick={alertFn}>alert</button></div></>)}export default Demo;

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

远程登录服务器(ubuntu20.04)在自己账号下的虚拟环境(python3.6)安装Jupyter并连接pycharm使用

参考&#xff1a;Jupyter notebook/lab安装及远程访问 1、安装jupyter pip install notebook遇到的问题&#xff1a; &#xff08;1&#xff09;运行这个指令之前尝试了好多方法都安不上 此前还尝试了更新pip之类的&#xff0c;大家安不上也可以先更新pip试试。 &#xff0…

JavaScript简介

目录 概要&#xff1a; 说明&#xff1a; 学习JS的原因&#xff1a; JS可以干什么&#xff1a; 了解JavaScript&#xff1a; 前言&#xff1a; JavaScript的历史&#xff1a; JavaScript与ECMAScript&#xff1a; 如何运行JavaScript以及JavaScrip的特点&#xff1a; …

基于Python的微博旅游情感分析、微博舆论可视化系统

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

HTML - 你知道b与strong标签的区别吗

难度级别&#xff1a;初级及以上 提问概率&#xff1a;50% 不单单是初学者&#xff0c;即便是有好几年工作经验的前端开发工作者&#xff0c;也会有一大部分人把这两个标签搞混&#xff0c;甚至在工作中&#xff0c;很大一部人不会使用这两个标…

玩转Django分页器

一、Pagination 分页器编程步骤 View, 导入django.core.paginator.Paginator类&#xff0c;创建Paginator 对象时&#xff0c;输入qs对象&#xff0c;以及每页显示条数。 接收 URL, 从请求参数中读取page数值 &#xff0c;通过 paginator.page(page_num) 返回请求页的page_obj…

电商好评语整理与优化:让繁琐工作变得轻松高效

在电子商务领域&#xff0c;客户的好评是店铺信誉和产品质量的重要体现。然而&#xff0c;整理和优化这些好评语却是一项既繁琐又需要细致耐心的工作。本文将探讨如何高效地进行电商好评语的筛选、分类和优化&#xff0c;让这一工作变得更加轻松和高效。 一、明确整理目的 在开…

环保用电监测系统诞生与作用

随着全球能源危机的加剧和环境保护意识的提高&#xff0c;环保用电监测系统应运而生。这一系统以其独特的监测能力、数据分析和节能减排功能&#xff0c;在提高用电效率和促进环境可持续发展方面发挥着重要作用。本文将从环保用电监测系统的诞生背景、主要功能、作用以及在实际…

语音识别:基于HMM

HMM语音识别的解码过程 从麦克风采集的输入音频波形被转换为固定尺寸的一组声学向量&#xff1a; 其中是维的语音特征向量&#xff08;例如MFCC&#xff09;。 解码器尝试去找到上述特征向量序列对应的单词&#xff08;word&#xff09;的序列&#xff1a; 单词序列的长度是。…

2024人工智能与机器人系统国际学术会议(ICAIRS2024)

2024人工智能与机器人系统国际学术会议(ICAIRS2024) 会议简介 2024人工智能与机器人系统国际学术会议(ICAIRS2024)将在杭州举行。该会议旨在为人工智能和机器人系统的专家学者提供一个平台&#xff0c;以分享最新的研究成果、交流思想、探讨学术问题&#xff0c;并促进跨学科…

Open3D(C++) 基于随机抽样与特征值法的点云平面稳健拟合方法

目录 一、算法原理1、论文概述2、参考文献二、代码实现三、结果展示四、测试数据本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的GPT爬虫。 一、算法原理 1、论文概述 针对点云数据含有异常值且传统拟合方法拟合结果不理想的情…

动态规划刷题(算法竞赛、蓝桥杯)--合唱队形(线性DP)

1、题目链接&#xff1a;[NOIP2004 提高组] 合唱队形 - 洛谷 #include <bits/stdc.h> using namespace std; int n,ans; int a[105],f[105][2];//f[i][2]中2表示正反两个方向int main(){cin>>n;for(int i1;i<n;i){cin>>a[i];}//正方向求最长上升子序列 a[…

总结UDP协议各类知识点

前言 本篇博客博主将详细地介绍UDP有关知识点&#xff0c;坐好板凳发车啦~ 一.UDP特点 1.无连接 UDP传输的过程类似于发短信&#xff0c;知道对端的IP和端口号就直接进行传输&#xff0c;不需要建立连接&#xff1b; 2.不可靠传输 没有任何的安全机制&#xff0c;发送端发…

C语言:文件操作(一)

目录 前言 1、为什么使用文件 2、什么是文件 2.1 程序文件 2.2 数据文件 2.3 文件名 3、文件的打开和关闭 3.1 文件指针 3.2 文件的打开和关闭 结&#xff08;一&#xff09; 前言 本篇文章将介绍C语言的文件操作&#xff0c;在后面的内容讲到&#xff1a;为什么使用文…

大数据设计为何要分层,行业常规设计会有几层数据

大数据设计通常采用分层结构的原因是为了提高数据管理的效率、降低系统复杂度、增强数据质量和可维护性。这种分层结构能够将数据按照不同的处理和应用需求进行分类和管理&#xff0c;从而更好地满足不同层次的数据处理和分析需求。行业常规设计中&#xff0c;数据通常按照以下…

C++11:声明 初始化

C11&#xff1a;声明 & 初始化 初始化{ }初始化initializer_list 声明autodecltypenullptr 初始化 { }初始化 在C98中&#xff0c;允许使用花括号{ }对数组或者结构体元素进行统一的列表初始化。 用{ }初始化数组&#xff1a; int arr[] { 1, 2, 3, 4, 5 };用{ }初始化…

Qt C++ | Qt 元对象系统、信号和槽及事件(第一集)

01 元对象系统 一、元对象系统基本概念 1、Qt 的元对象系统提供的功能有:对象间通信的信号和槽机制、运行时类型信息和动态属性系统等。 2、元对象系统是 Qt 对原有的 C++进行的一些扩展,主要是为实现信号和槽机制而引入的, 信号和槽机制是 Qt 的核心特征。 3、要使用元…

VMware虚拟机三种网络模式配置

vmware有三种网络工作模式&#xff1a;Bridged&#xff08;桥接模式&#xff09;、NAT&#xff08;网络地址转换模式&#xff09;、Host-Only&#xff08;仅主机模式&#xff09;。 1. 打开网络编辑器&#xff08;编辑 --> 虚拟网络编辑器&#xff09; 在主机上有VMware Ne…

【阿里淘天笔试题汇总】2024-04-03-阿里淘天春招笔试题(第一套)-三语言题解(CPP/Python/Java)

&#x1f36d; 大家好这里是KK爱Coding &#xff0c;一枚热爱算法的程序员 ✨ 本系列打算持续跟新淘天近期的春秋招笔试题汇总&#xff5e; &#x1f4bb; ACM银牌&#x1f948;| 多次AK大厂笔试 &#xff5c; 编程一对一辅导 &#x1f44f; 感谢大家的订阅➕ 和 喜欢&#x1f…

[RK3588-Android12] 调试MIPI-双通道-压缩屏(Video Mode/MIPI Dphy 8Lane/DSC 144HZ)

问题描述 被测屏幕&#xff1a;小米Pad6 分辨率&#xff1a;1800X2880 模式&#xff1a;Video Mode/MIPI Dphy 8Lane/DSC 144HZ PPS: 11 00 00 89 30 80 0B 40 03 84 00 14 01 C2 01 C2 02 00 01 F4 00 20 01 AB 00 06 00 0D 05 7A 06 1A 18 00 10 F0 03 0C 20 00 06 0B 0B 33…

[Leetcode笔记] 动态规划相关

前言 写题目写到了一些和动态规划相关的内容&#xff0c;所以在这里记录一下 LCR 089 题解思路 总的来说&#xff0c;就是用一个数组去存储当前的最优解&#xff0c;然后从0开始一路向上顺推过去&#xff0c;求得最后一位的最优解。 class Solution { public:int rob(vect…