react 中的useState useEffect

2024-08-23 11:20

本文主要是介绍react 中的useState useEffect,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

下面的这些hook我们常用的一些

useState  useEffect useCallback、useMemo、useRef 和 useContex

下一个文章中讲述(useCallback、useMemo、useRef 和 useContex)

下面我将讲解什么时候使用是最好的

首先我们需要明确的一点是,这些hook都是在做缓存。

目录

Hooks 是如何诞生的?

useState:让函数组件具有维持状态的能力

useEffect:执行副作用

理解 Hooks 的依赖


Hooks 是如何诞生的?

其实顺着函数组件的思路思考,就会发现,如果我们想要让函数组件更有用,目标就是给函数组件加上状态。这看上去似乎并不是难事。简单想一下,函数和对象不同,并没有一个实例的对象能够在多次执行之间保存状态,那势必需要一个函数之外的空间来保存这个状态,而且要能够检测其变化,从而能够触发函数组件的重新渲染。再进一步想,那我们是不是就是需要这样一个机制,能够把一个外部的数据绑定到函数的执行。当数据变化时,函数能够自动重新执行。这样的话,任何会影响 UI 展现的外部数据,都可以通过这个机制绑定到 React 的函数组件。在 React 中,这个机制就是 Hooks。所以我们现在也能够理解这个机制为什么叫 Hooks 了。顾名思义,Hook 就是“钩子”的意思。在 React 中,Hooks 就是把某个目标结果钩到某个可能会变化的数据源或者事件源上,那么当被钩到的数据或事件发生变化时,产生这个目标结果的代码会重新执行,产生更新后的结果。

useState:让函数组件具有维持状态的能力

React 的核心机制是能够在数据发生变化的时候自动重新渲染 UI,那么势必要有一个让我们保存状态的地方,这个保存状态的机制就是 state。

在函数组件中,我们可以使用 useState 这样一个 Hook 来保存状态,那么状态在发生变化时,也会让 UI 自动发生变化。比如下面这段代码,展示了一个简单计数器的实现的例子

import React from "react";export default function Counter() {const [count, setCount] = React.useState(0);return (<div><button onClick={() => setCount(count + 1)}>{count}</button></div>);
}

state 是 React 组件非常重要的一个机制,那么什么样的值应该保存在 state 中呢?这是日常开发中需要经常思考的问题。通常来说,我们要遵循的一个原则就是:state 中永远不要保存可以通过计算得到的值。比如说:

  1. 从 props 传递过来的值。有时候 props 传递过来的值无法直接使用,而是要通过一定的计算后再在 UI 上展示,比如说排序。那么我们要做的就是每次用的时候,都重新排序一下,或者利用某些 cache 机制,而不是将结果直接放到 state 里。
  2. 从 URL 中读到的值。比如有时需要读取 URL 中的参数,把它作为组件的一部分状态。那么我们可以在每次需要用的时候从 URL 中读取,而不是读出来直接放到 state 里。
  3. 从 cookie、localStorage 中读取的值。通常来说,也是每次要用的时候直接去读取,而不是读出来后放到 state 里。

不过,state 虽然便于维护状态,但也有自己的弊端。一旦组件有自己状态,意味着组件如果重新创建,就需要有恢复状态的过程,这通常会让组件变得更复杂。

useEffect:执行副作用

什么是副作用呢?通常来说,副作用是指一段和当前执行结果无关的代码。比如说要修改函数外部的某个变量,要发起一个请求,等等。也就是说,在函数组件的当次执行过程中,useEffect 中代码的执行是不影响渲染出来的 UI 的。

useEffect(callback, dependencies)

你只要记住,useEffect 是每次组件 render 完后判断依赖并执行就可以了。

总结一下,useEffect 让我们能够在下面四种时机去执行一个回调函数产生副作用:

  1. 每次 render 后执行:不提供第二个依赖项参数。比如useEffect(() => {})。
  2. 仅第一次 render 后执行:提供一个空数组作为依赖项。比如useEffect(() => {}, [])。
  3. 第一次以及依赖项发生变化后执行:提供依赖项数组。比如useEffect(() => {}, [deps])。
  4. 组件 unmount 后执行:返回一个回调函数。比如useEffect() => { return () => {} }, [])。

理解 Hooks 的依赖

在 useEffect Hook 中你已经看到了依赖项的概念。其实除了在 useEffect 中会用到外,在第 5 讲的 useCallback 和 useMemo 中也会用到。所以接下来我们就先透彻了解它的工作机制,帮助你在实际开发中能够正确地使用。

Hooks 提供了让你监听某个数据变化的能力。这个变化可能会触发组件的刷新,也可能是去创建一个副作用,又或者是刷新一个缓存。那么定义要监听哪些数据变化的机制,其实就是指定 Hooks 的依赖项。

不过需要注意的是,依赖项并不是内置 Hooks 的一个特殊机制,而可以认为是一种设计模式。有类似需求的 Hooks 都可以用这种模式去实现。

那么在定义依赖项时,我们需要注意以下三点:

  1. 依赖项中定义的变量一定是会在回调函数中用到的,否则声明依赖项其实是没有意义的。
  2. 依赖项一般是一个常量数组,而不是一个变量。因为一般在创建 callback 的时候,你其实非常清楚其中要用到哪些依赖项了。
  3. React 会使用浅比较来对比依赖项是否发生了变化,所以要特别注意数组或者对象类型。如果你是每次创建一个新对象,即使和之前的值是等价的,也会被认为是依赖项发生了变化。这是一个刚开始使用 Hooks 时很容易导致 Bug 的地方。例如下面的代码:
function Sample() {// 这里在每次组件执行时创建了一个新数组const todos = [{ text: 'Learn hooks.'}];useEffect(() => {console.log('Todos changed.');}, [todos]);
}

代码的原意可能是在 todos 变化的时候去产生一些副作用,但是这里的 todos 变量是在函数内创建的,实际上每次都产生了一个新数组。所以在作为依赖项的时候进行引用的比较,实际上被认为是发生了变化的。

这篇关于react 中的useState useEffect的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1099241

相关文章

HTML5中的Microdata与历史记录管理详解

《HTML5中的Microdata与历史记录管理详解》Microdata作为HTML5新增的一个特性,它允许开发者在HTML文档中添加更多的语义信息,以便于搜索引擎和浏览器更好地理解页面内容,本文将探... 目录html5中的Mijscrodata与历史记录管理背景简介html5中的Microdata使用M

html5的响应式布局的方法示例详解

《html5的响应式布局的方法示例详解》:本文主要介绍了HTML5中使用媒体查询和Flexbox进行响应式布局的方法,简要介绍了CSSGrid布局的基础知识和如何实现自动换行的网格布局,详细内容请阅读本文,希望能对你有所帮助... 一 使用媒体查询响应式布局        使用的参数@media这是常用的

HTML5表格语法格式详解

《HTML5表格语法格式详解》在HTML语法中,表格主要通过table、tr和td3个标签构成,本文通过实例代码讲解HTML5表格语法格式,感兴趣的朋友一起看看吧... 目录一、表格1.表格语法格式2.表格属性 3.例子二、不规则表格1.跨行2.跨列3.例子一、表格在html语法中,表格主要通过< tab

Vue3组件中getCurrentInstance()获取App实例,但是返回null的解决方案

《Vue3组件中getCurrentInstance()获取App实例,但是返回null的解决方案》:本文主要介绍Vue3组件中getCurrentInstance()获取App实例,但是返回nu... 目录vue3组件中getCurrentInstajavascriptnce()获取App实例,但是返回n

JS+HTML实现在线图片水印添加工具

《JS+HTML实现在线图片水印添加工具》在社交媒体和内容创作日益频繁的今天,如何保护原创内容、展示品牌身份成了一个不得不面对的问题,本文将实现一个完全基于HTML+CSS构建的现代化图片水印在线工具... 目录概述功能亮点使用方法技术解析延伸思考运行效果项目源码下载总结概述在社交媒体和内容创作日益频繁的

前端CSS Grid 布局示例详解

《前端CSSGrid布局示例详解》CSSGrid是一种二维布局系统,可以同时控制行和列,相比Flex(一维布局),更适合用在整体页面布局或复杂模块结构中,:本文主要介绍前端CSSGri... 目录css Grid 布局详解(通俗易懂版)一、概述二、基础概念三、创建 Grid 容器四、定义网格行和列五、设置行

前端下载文件时如何后端返回的文件流一些常见方法

《前端下载文件时如何后端返回的文件流一些常见方法》:本文主要介绍前端下载文件时如何后端返回的文件流一些常见方法,包括使用Blob和URL.createObjectURL创建下载链接,以及处理带有C... 目录1. 使用 Blob 和 URL.createObjectURL 创建下载链接例子:使用 Blob

Vuex Actions多参数传递的解决方案

《VuexActions多参数传递的解决方案》在Vuex中,actions的设计默认只支持单个参数传递,这有时会限制我们的使用场景,下面我将详细介绍几种处理多参数传递的解决方案,从基础到高级,... 目录一、对象封装法(推荐)二、参数解构法三、柯里化函数法四、Payload 工厂函数五、TypeScript

Vue3使用router,params传参为空问题

《Vue3使用router,params传参为空问题》:本文主要介绍Vue3使用router,params传参为空问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录vue3使用China编程router,params传参为空1.使用query方式传参2.使用 Histo

CSS Padding 和 Margin 区别全解析

《CSSPadding和Margin区别全解析》CSS中的padding和margin是两个非常基础且重要的属性,它们用于控制元素周围的空白区域,本文将详细介绍padding和... 目录css Padding 和 Margin 全解析1. Padding: 内边距2. Margin: 外边距3. Padd