React学习笔记:实用又好用的Hooks函数

news2024/10/6 12:20:26

React框架以前是采用Class类编程,在类编程中使用生命周期比较方便,但是随着迭代更新,官方开始推荐使用函数式编程,但是函数式编程就没有状态这一个概念,于是乎官方就定义了一系列钩子函数来弥补在这一缺陷,那今天我们就来学习几个实用又好用的Hooks函数。

本文是基于个人的学习分享,可能不是特别全面,本文使用的是18版本的react,使用脚手架搭建的项目。

Hooks

动机:

1.解决组件的逻辑复用。
2.解决一些class类中存在的一些问题。

定义: Hook顾名思义就是钩子的意思,在函数组件中将React的class类组件中状态以及生命周期等这些特性引入到函数组件中,这就是React的Hook函数。所以在类组件中就是不能使用hook函数。

useState

之前的函数式组件,也被称之为无状态组件,只能接受父组件传过来的props做展示,函数式组件中没有state状态也没有生命周期,而 state Hook 可以让函数式组件使用状态。

useState是React中的一个Hook函数,它是一个方法,调用的时候传入一个默认值,返回的是一个数组,其中第一项是默认状态(默认值会赋予状态),数组第二项是一个用于更新设置默认值都的函数。

因为写数组下标去获取比较麻烦,所以采用了ES6中数组的结构,直接获取到一个状态值和修改状态值的函数。

让我们用一个例子来体会一下,其中的妙用,首先需要从react中引入useState

import { useState } from 'react';

function Demo() {const [count,setCount] = useState(0);const [name,setName] = useState('寒月十九');return (<div><h3>{name}</h3><button onClick={() => { setName('十九') }}>change</button><h3>{count}</h3><button onClick={() => { setCount(count + 1) }}>add</button></div>);
} 

所以useState支持多次调用,并且每一次调用返回的都是一个新的状态。

useEffect

在类组件中可以在componentDidMount组件首次渲染结束和componentDidUpdate组件更新中执行副作用,那在useEffect这个钩子函数中,通过传递的参数不同,实现不同的生命周期的效果。我们直接用实际效果直观感受一下。

首先useEffect接收两个参数,第一个参数是一个回调函数,第二个参数为依赖。

1.只传一个参数,并且里面没有返回值

import { useState } from 'react';

function Demo() {const [count,setCount] = useState(0);const [name,setName] = useState('寒月十九');useEffect(() => {console.log('副作用执行了!');})return (<div><h3>{name}</h3><button onClick={() => { setName('十九') }}>change</button><h3>{count}</h3><button onClick={() => { setCount(count + 1) }}>add</button></div>);
} 

当组件渲染结束会执行一次,一加载有两次打印是因为解析jsx文件时为了解析为浏览器能读的懂得文件时,有一次组件的卸载,并再执行一次组建的渲染;当组件每次更新时都会触发这个钩子函数,相当于 ComponentDidUpdate 组件更新时。

2.只传一个参数,并且里面有返回值(返回出一个函数)

useEffect(() => { console.log('副作用执行了!'); return () => {console.log('清除副作用!'); }
 }) 

当useEffect传递一个参数并且第一个参数返回出一个函数,这个函数可以在组件卸载时清除副作用,也就是说相当于生命周期中的 componentWillUnmount 组件卸载时。

3.传递两个参数,第一个参数为回调,第二个参数为空数组时

import { useState } from 'react';

function Demo() {const [count,setCount] = useState(0);const [name,setName] = useState('寒月十九');useEffect(() => {console.log('副作用执行了!');},[])return (<div><h3>{name}</h3><button onClick={() => { setName('十九') }}>change</button><h3>{count}</h3><button onClick={() => { setCount(count + 1) }}>add</button></div>);
} 

当第二个参数依赖为空数组时,useEffect钩子函数只会在组件渲染结束执行一次,那么就相当于ComponentDidMount 组件渲染结束时。通常我们会在这个钩子函数发接口请求。

4.传递两个参数,第一个参数为回调,第二个参数为基本类型时

import { useState } from 'react';

function Demo() {const [count,setCount] = useState(0);const [name,setName] = useState('寒月十九');useEffect(() => {console.log('副作用执行了!');},[count])return (<div><h3>{name}</h3><button onClick={() => { setName('十九') }}>change</button><h3>{count}</h3><button onClick={() => { setCount(count + 1) }}>add</button></div>);
} 

当第二个参数设置的基本类型发生改变时才会执行这个钩子函数,而不是当组件发生更新就执行。

我们可以记住useEffect设个钩子函数比较强大,当设置的参数不同时,可以分别代替 ComponentDidMount 、 ComponentDidUpdate 、 ComponentWillUnmount 三个生命周期的使用。

当然这个钩子函数当然不止这么几种参数配置,由于是学习笔记,并不算全面。

useRef

useRef返回一个可变的ref对象,useRef接受一个参数绑定在返回的ref对象的current属性上,返回的ref对象在整个生命周期中保持不变。

import { useRef,useEffect } from 'react';

function Demo3() {const h1Ref = useRef(null);useEffect(() => {console.log(h1Ref);},[]);return (<div><h1 ref={h1Ref}>this is h1</h1></div>)
} 

useContext

这个钩子函数主要用于爷孙组件传值,useContext Hook接受一个context对象(由createContext创建的对象)作为参数,并返回Context.Consumer。

import { createContext,useContext,useState } from 'react';

const Context = createContext();// 创建一个上下文对象

function Bar() {const name = useContext(Context)return <div>Bar -- 从Demo4接收的参数:{name}</div>
}

function Foo() {return (<div>Foo<Bar /></div>)
}

function Demo4() {return (<div><Context.Provider value={'寒月十九'}><Foo /></Context.Provider></div>)
} 

Bar作为Foo的子组件,Foo又是Demo中的子组件,我们使用Context组件中的Provide方法给子组件传值,必须使用value传值。

如果我传递的值是Demo4中一个有响应式的值,那子组件取到的值也会是响应式的吗?

import { createContext,useContext,useState } from 'react';

const Context = createContext();// 创建一个上下文对象

function Bar() {const name = useContext(Context)return <div>Bar --从Demo4接收的参数:{name}</div>
}

function Foo() {return (<div>Foo<Bar /></div>)
}

function Demo4() {const [name,setName] = useState('寒月十九');return (<div><Context.Provider value={name}><Foo /><button onClick={() => setName('十九')}>changeName</button></Context.Provider></div>)
} 

可以看出,子组件接收到的啊参数也是响应式的。

最后

最近还整理一份JavaScript与ES的笔记,一共25个重要的知识点,对每个知识点都进行了讲解和分析。能帮你快速掌握JavaScript与ES的相关知识,提升工作效率。



有需要的小伙伴,可以点击下方卡片领取,无偿分享

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

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

相关文章

Rabbitmq(七) -- rabbitmq的工作模式

1. 简单模式&#xff1a;无需交换机 消息产生消息&#xff0c;将消息放入队列消息的消费者(consumer) 监听 消息队列,如果队列中有消息,就消费掉,消息被拿走后,自动从队列中删除(隐患 消息可能没有被消费者正确处理,已经从队列中消失了,造成消息的丢失&#xff0c;这里可以设置…

VTK-数据集vtkUnstructuredGrid

前言&#xff1a;本博文主要介绍vtkUnstructuredGrid的特点、结构组成&#xff0c;vtkUnstructuredGrid的创建方法&#xff0c;及其vtkUnstructuredGrid相关的接口及示例。 特点 非结构化网格数据&#xff0c;是最常见的数据集类型&#xff0c;它的拓扑结构和几何结构都是非结…

Pycharm调试功能介绍

文章目录pycharm中的debug模式debug的断点调试pycharm中的debug模式 在pycharm中&#xff0c;一共有4中方法开启debug调试&#xff0c;如下&#xff1a; 点击导航栏的run >> debug 双击打开py文件 >> 右上角点击小虫子图标。 写好if name ‘main’: >> 点…

React 类组件你不知道的细节+案例

React基础-组件-类组件 1.组件概述 目标&#xff1a;了解React组件的作用和创建组件的方式 什么是组件组件的设计思想 1.what is 组件啊&#xff1f; 在前端开发中组件就是用户界面当中一块独立的区域,在组件内部会包含这块区域中的视图代码,样式代码以及逻辑代码 React是采用…

Cadence PCB仿真使用Allegro PCB SI配置差分对的方法图文教程

⏪《上一篇》   🏡《总目录》   ⏩《下一篇》 目录 1,概述2,配置方法3,总结1,概述 本文简单介绍使用Allegro PCB SI配置差分对的方法。 2,配置方法 第1步:打开待仿真的PCB文件,并确认软件为Allegro PCB SI 如果,打开软件不是Allegro PCB SI则可这样切换 执行Fil…

天下苦“个人公众号认证”久矣,吾闻今可

大家好&#xff0c;我是小悟 一看到个人公众号可以认证&#xff0c;便以迅雷不及掩耳之势准备资料&#xff0c;一顿操作猛如虎后&#xff0c;我的号终于认证啦。 看到别人的个人公众号有认证的&#xff0c;这两天我就在想要怎么才能认证&#xff0c;于是就去搜索相关的内容&am…

电子采购系统的优势是什么 常用的电子采购系统介绍

采购是企业发展中的重要环节之一。在企业采购流程中&#xff0c;并不是简单的完成买和卖就行了&#xff0c;这其中还会涉及到各个方面。例如&#xff0c;在企业采购活动中&#xff0c;常常会遇到供应商数据维护难&#xff0c;采购成本把控难&#xff0c;供应商筛选难等问题。而…

面对集中式缓存实现上的挑战,Redis交出的是何种答卷?聊聊Redis在分布式方面的能力设计

大家好&#xff0c;又见面了。 本文是笔者作为掘金技术社区签约作者的身份输出的缓存专栏系列内容&#xff0c;将会通过系列专题&#xff0c;讲清楚缓存的方方面面。如果感兴趣&#xff0c;欢迎关注以获取后续更新。 在本专栏前面的文章中&#xff0c;我们介绍了各种本地缓存框…

数据结构与算法1—线性表

1. 线性表的定义 线性表L是n&#xff08;n≥0&#xff09;个具有相同属性的数据元素a1&#xff0c;a2&#xff0c;a3&#xff0c;…&#xff0c;an组成的有限序列&#xff0c;其中序列中元素的个数n称为线性表的长度。当n0时称为空表&#xff0c;即不含有任何元素。常常将非空…

express接口

文章目录什么是接口创建 API 路由模块编写 GET 接口编写 POST 接口完整代码CORS 跨域资源共享使用 CORS 中间件解决跨域问题实现 JSONP 接口什么是接口 API (Application Programming Interface&#xff0c;应用程序编程接口 ) 是一些预先定义的函数&#xff0c;目的是提供应用…

TCP/IP 网络模型有哪几层

备注&#xff1a;本文参考小林coding相关内容&#xff0c;侵权请联系作者删除 1.应用层 最上层的&#xff0c;也是我们能直接接触到的就是应用层&#xff08;Application Layer&#xff09;&#xff0c;我们电脑或手机使用的应用软件都是在应用层实现。那么&#xff0c;当两个…

高并发系统设计 -- 登录系统设计

同源策略 同源策略是一种安全策略。是游览器最核心最基本的安全功能。防止XSS&#xff0c;CSFR等攻击具体表现是游览器在执行脚本之前&#xff0c;会判断脚本是否与打开的网页是同源的&#xff0c;也就是协议&#xff0c;域名&#xff0c;端口是否都相同&#xff0c;相同就是同…

记录--前端性能监控初步实战

这里给大家分享我在网上总结出来的一些知识&#xff0c;希望对大家有所帮助 前言 在当下前后端分离的主流环境下&#xff0c;前端部分的优化变得越来越重要。为了提升前端的性能和用户体验&#xff0c;我觉得可能需要从三个维度采集数据进行分析。 前端埋点。通过埋点收集和统计…

SCRM与CRM的区别

当私域流量的概念兴起时&#xff0c;企业直接触达用户的场景也越来越丰富&#xff0c;SCRM形式的私域运营已然成为很多企业数字化转型布局的关键阵地。 前言 当私域流量的概念兴起时&#xff0c;企业直接触达用户的场景也越来越丰富&#xff0c;SCRM形式的私域运营已然成为很多…

服务器部署所有前后端分离项目

1、Linux服务器安装好jdk、mysql、redis、node 2、拉取最新代码 gitee仓库项目地址&#xff1a;https://gitee.com/y_project/RuoYi-Vue 拉取代码到本地 3、修改后端配置 3.1、修改系统内上传文件位置的配置&#xff1a; 默认是windows系统的配置&#xff0c;将此配置修改…

JMeter接口测试使用教程哪里有?

JMeter接口测试使用教程哪里有&#xff1f;接口测试是测试工程师的必备技能之一&#xff0c;运用JMeter工具一步步实现接口请求&#xff0c;数据参数化&#xff0c;断言等操作&#xff0c;通过常见的企业实际测试场景详解JMeter各项技术使用&#xff0c;最后结合Jenkins持续集成…

Django搭建个人博客Blog-Day01

创建虚拟环境虚拟环境相当于一个抽屉&#xff0c;在这个抽屉里面安装的任何软件&#xff0c;都不会影响到其他抽屉&#xff0c;所以利用虚拟环境就可以做到同时安装不同版本的第三方库&#xff0c;而互不影响。使用虚拟环境的目的是为了防止一些第三方库出现版本不兼容问题&…

c++11 标准模板(STL)(std::forward_list)(五)

定义于头文件 <forward_list> template< class T, class Allocator std::allocator<T> > class forward_list;(1)(C11 起)namespace pmr { template <class T> using forward_list std::forward_list<T, std::pmr::polymorphic_…

当我们在谈论DataOps时,我们到底在谈论什么

1. DataOps到底是什么&#xff1f; 伴随着全球数字化转型的高速发展&#xff0c;在云计算、物联网、5G、边缘计算、元宇宙等新技术的驱动下&#xff0c;数据爆炸的时代已经来临。IDC Global DataSphere显示&#xff0c;2021年&#xff0c;全球数据总量达到了84.5ZB&#xff0c…

Java多线程案例——阻塞队列(生产者消费者模型)

一&#xff0c;阻塞队列1.阻塞队列的概念和作用阻塞队列同数据结构中的队列一样都遵守“先进先出”的原则&#xff08;不了解队列相关知识的朋友请查看之前队列的博文&#xff1a;(6条消息) 栈和队列&#xff08;内附模拟实现代码&#xff09;_徐憨憨&#xff01;的博客-CSDN博…