react之Hooks的介紹、useState與useEffect副作用的使用

react之Hooks的介紹、useState與useEffect副作用的使用

  • 一、Hooks的基本介紹
  • 二、useState的使用
    • 2.1 簡單使用
    • 2.2 數組結構簡化
    • 2.3 狀態的讀取和修改
    • 2.3 組件的更新過程
  • 三、useEffect的使用
    • 3.1 副作用介紹
    • 3.2 基本使用
    • 3.3 依賴
    • 3.4 不要對依賴項撒謊
    • 3.5 依賴項可以是空數組
    • 3.6 清理工作
    • 3.7 useEffect的 4 種使用使用方式
    • 3.8 發送請求
    • 3.9 axios請求本地json數據

一、Hooks的基本介紹

  • Hooks 是 React v16.8 中的新增功能
  • 為函數組件提供狀態、生命周期等原本 class 組件中提供的 React 功能
  • 可以理解為通過 Hooks 為函數組件鉤入 class 組件的特性
  • 注意:Hooks 只能在函數組件中使用,自此,函數組件成為 React 的新寵兒
  • 可以在項目中同時使用hooks和class

二、useState的使用

2.1 簡單使用

  • 一個 Hook 就是一個特殊的函數,讓你在函數組件中獲取狀態等 React 特性
  • useState使用場景:當你想要在函數組件中,使用組件狀態時,就要使用 useState Hook 了
  • useState作用:為函數組件提供狀態(state)
import { useState } from 'react'const Count = () => {  // stateArray 是一個數組const stateArray = useState(0)const state = stateArray[0]const setState = stateArray[1]return (<div>{/* 展示狀態值 */}<h1>狀態為:{state}</h1>{/* 點擊按鈕,讓狀態值 +1 */}<button onClick={() => setState(state + 1)}>+1</button></div>)
}

2.2 數組結構簡化

import { useState } from 'react'const Count = () => {// 解構:const [count, setCount] = useState(0)return (<div><h1>計數器:{state}</h1><button onClick={() => setState(state + 1)}>+1</button></div>)
}

2.3 狀態的讀取和修改

  • 讀取狀態:useState 提供的狀態,是函數內部的局部變量,可以在函數內的任意位置使用
const Counter = () => {const [user, setUser] = useState({ name: 'jack', age: 18 })return (<div><p>姓名:{user.name}</p><p>年齡:{user.age}</p></div>)
}

修改狀態:

  • setCount(newValue) 是一個函數,參數表示:新的狀態值
    • 調用該函數后,將使用新的狀態值替換舊值
    • 修改狀態后,因為狀態發生了改變,所以,該組件會重新渲染
const Counter = () => {const [user, setUser] = useState({ name: 'jack', age: 18 })const onAgeAdd = () => {setUser({...user,age: user.age + 1})}return (<div><p>姓名:{user.name}</p><p>年齡:{user.age}</p><button onClick={onAgeAdd}>年齡+1</button></div>)
}
  • 修改狀態的時候,一定要使用新的狀態替換舊的狀態

2.3 組件的更新過程

函數組件使用 useState hook 后的執行過程,以及狀態值的變化:

  • 組件第一次渲染:
    • 1.從頭開始執行該組件中的代碼邏輯
    • 2.調用 useState(0) 將傳入的參數作為狀態初始值,即:0
    • 3.渲染組件,此時,獲取到的狀態 count 值為: 0
  • 組件第二次渲染:
    • 1.點擊按鈕,調用 setCount(count + 1) 修改狀態,因為狀態發生改變,所以,該組件會重新渲染
    • 2.組件重新渲染時,會再次執行該組件中的代碼邏輯
    • 3.再次調用 useState(0),此時 React 內部會拿到最新的狀態值而非初始值,比如,該案例中最新的狀態值為 1
    • 4.再次渲染組件,此時,獲取到的狀態 count 值為:1
  • useState 的初始值(參數)只會在組件第一次渲染時生效

核心代碼

import { useState } from 'react'const Count = () => {const [count, setCount] = useState(0)return (<div><h1>計數器:{count}</h1><button onClick={() => setCount(count + 1)}>+1</button></div>)
}

三、useEffect的使用

3.1 副作用介紹

內容:

  • 使用場景:當你想要在函數組件中,處理副作用(side effect)時,就要使用 useEffect Hook 了

  • 作用:處理函數組件中的副作用(side effect)

  • 問題:副作用(side effect)是什么?

  • 回答:在計算機科學中,如果一個函數或其他操作修改了其局部環境之外的狀態變量值,那么它就被稱為有副作用
    類比,對于 999 感冒靈感冒藥來說:

  • (主)作用:用于感冒引起的頭痛,發熱,鼻塞,流涕,咽痛等

  • 副作用:可見困倦、嗜睡、口渴、虛弱感

  • 理解:副作用是相對于主作用來說的,一個功能(比如,函數)除了主作用,其他的作用就是副作用

  • 對于 React 組件來說,主作用就是根據數據(state/props)渲染 UI,除此之外都是副作用(比如,手動修改 DOM)

  • 常見的副作用(side effect):數據(Ajax)請求、手動修改 DOM、localStorage、console.log 操作等

總結

? 對于react組件來說,除了渲染UI之外的其他操作,都可以稱之為副作用

let a = 1const Count = () => {const [count, setCount] = useState(0)const handleClick = () => {setCount(count + 1)}console.log('aaa')axios.post('http://xxx')localStorage.setItem()a = 2return (<div><h1>計數器:{count}</h1><button onClick={handleClick}>+1</button></div>)
}

3.2 基本使用

  • 使用場景:當你想要在函數組件中,處理副作用(side effect)時就要使用 useEffect Hook 了

  • 作用:處理函數組件中的一些副作用(side effect)

  • 注意:在實際開發中,副作用是不可避免的。因此,react 專門提供了 useEffect Hook 來處理函數組件中的副作用

語法:

  • 參數:回調函數(稱為 effect),就是在該函數中寫副作用代碼
  • 執行時機:該 effect 會在組件第一次渲染以及每次組件更新后執行
  • 相當于 componentDidMount + componentDidUpdate

核心代碼

import { useEffect } from 'react'const Counter = () => {const [count, setCount] = useState(0)useEffect(() => {document.title = `當前已點擊 ${count}`})return (<div><h1>計數器:{count}</h1><button onClick={() => setCount(count + 1)}>+1</button></div>)
}

3.3 依賴

內容:

  • 問題:如果組件中有另外一個狀態,另一個狀態更新時,剛剛的 effect 回調也會執行

  • 默認情況:只要狀態發生更新 useEffect 的 effect 回調就會執行

  • 性能優化:跳過不必要的執行,只在 count 變化時,才執行相應的 effect

  • 語法:

    • 第二個參數:可選,也可以傳一個數組,數組中的元素可以成為依賴項(deps)
    • 該示例中表示:只有當 count 改變時,才會重新執行該 effect

    核心代碼

import { useEffect } from 'react'const Counter = () => {const [count, setCount] = useState(0)const [loading, setLoading] = useState(false)useEffect(() => {document.title = `當前已點擊 ${count}`}, [count])return (<div><h1>計數器:{count}</h1><button onClick={() => setCount(count + 1)}>+1</button><button onClick={() => setLoading(!loading)}>切換 loading</button></div>)
}

3.4 不要對依賴項撒謊

內容:

  • useEffect 回調函數(effect)中用到的數據(比如,count)就是依賴數據,就應該出現在依賴項數組中
  • 如果 useEffect 回調函數中用到了某個數據,但是,沒有出現在依賴項數組中,就會導致一些 Bug 出現!
  • 所以,不要對 useEffect 的依賴撒謊
const App = () => {const [count, setCount] = useState(0)// 錯誤演示:useEffect(() => {document.title = '點擊了' + count + '次'}, [])return (<div><h1>計數器:{count}</h1><button onClick={() => setCount(count + 1)}>+1</button></div>)
}

useEffect完全指南:https://overreacted.io/zh-hans/a-complete-guide-to-useeffect/

3.5 依賴項可以是空數組

內容

  • useEffect 的第二個參數,還可以是一個空數組([]),表示只在組件第一次渲染后執行 effect

  • 使用場景:1 事件綁定 2 發送請求獲取數據 等

  • 語法:

    • 該 effect 只會在組件第一次渲染后執行,因此,可以執行像事件綁定等只需要執行一次的操作
    • 此時,相當于 class 組件的 componentDidMount 鉤子函數的作用
useEffect(() => {const handleResize = () => {}window.addEventListener('resize', handleResize)
}, [])

注意:

  • 跟 useState Hook 一樣,一個組件中也可以調用 useEffect Hook 多次
  • 推薦:一個 useEffect 只處理一個功能,有多個功能時,使用多次 useEffect

3.6 清理工作

內容:

  • effect 的返回值是可選的,可省略。也可以返回一個清理函數,用來執行事件解綁等清理操作
  • 清理函數的執行時機:
    • 清理函數會在組件卸載時以及下一次副作用回調函數調用的時候執行,用于清除上一次的副作用。
    • 如果依賴項為空數組,那么會在組件卸載時會執行。相當于組件的componetWillUnmount

核心代碼:

useEffect(() => {const handleResize = () => {}window.addEventListener('resize', handleResize)// 這個返回的函數,會在該組件卸載時來執行// 因此,可以去執行一些清理操作,比如,解綁 window 的事件、清理定時器 等return () => window.removeEventListener('resize', handleResize)
}, [])

3.7 useEffect的 4 種使用使用方式

// 1
// 觸發時機:1 第一次渲染會執行 2 每次組件重新渲染都會再次執行
// componentDidMount + ComponentDidUpdate
useEffect(() => {})// 2(使用頻率最高)
// 觸發時機:只在組件第一次渲染時執行
// componentDidMount
useEffect(() => {}, [])// 3(使用頻率最高)
// 觸發時機:1 第一次渲染會執行 2 當 count 變化時會再次執行
// componentDidMount + componentDidUpdate(判斷 count 有沒有改變)
useEffect(() => {}, [count])// 4
useEffect(() => {// 返回值函數的執行時機:組件卸載時// 在返回的函數中,清理工作return () => {// 相當于 componentWillUnmount}
}, [])useEffect(() => {// 返回值函數的執行時機:1 組件卸載時 2 count 變化時// 在返回的函數中,清理工作return () => {}
}, [count])

3.8 發送請求

內容:

  • 在組件中,可以使用 useEffect Hook 來發送請求(side effect)獲取數據

  • 注意:effect 只能是一個同步函數,不能使用 async

    • 因為如果 effect 是 async 的,此時返回值是 Promise 對象。這樣的話,就無法保證清理函數被立即調用
  • 為了使用 async/await 語法,可以在 effect 內部創建 async 函數,并調用

核心代碼:

// 錯誤演示:不要給 effect 添加 async
useEffect(async () => {const res = await axios.get('http://xxx')return () => {}
}, [])// 正確使用
useEffect(() => {const loadData = async () => {const res = await axios.get('http://xxx')}loadData()return () => {}
}, [])

3.9 axios請求本地json數據

  • 需求:發起axios請求本地某json數據
  • 第一步:需要將json文件放在 public 目錄下 !!!
  • 第二步:引入axios import axios from 'axios'
  • 第三步:發起請求
import React, { useEffect, useState } from 'react'
import axios from 'axios'
export default function App() {const [list, setList] = useState([])useEffect(() => {
//接口地址可省略 public    
axios.get('http://localhost:3000/data.json').then((res) => {console.log('打印res', res.data)setList(res.data.list)})}, [])return (<ul>{list.map((item) => (<li key={item.id}>{item.comment}</li>))}</ul>)
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/39650.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/39650.shtml
英文地址,請注明出處:http://en.pswp.cn/news/39650.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ZZULIOJ 1193: 單科成績排序(結構體專題),Java

ZZULIOJ 1193: 單科成績排序&#xff08;結構體專題&#xff09;&#xff0c;Java 題目描述 有一學生成績表&#xff0c;包括學號、姓名、3門課程成績。請按要求排序輸出&#xff1a;若輸入1&#xff0c;則按第1門課成績降序輸出成績表&#xff0c;若輸入為i&#xff08;1<…

清風數學建模——擬合算法

擬合算法 文章目錄 擬合算法概念 確定擬合曲線最小二乘法的幾何解釋求解最小二乘法matlab求解最小二乘法如何評價擬合的好壞計算擬合優度的代碼 概念 在前面的篇幅中提到可以使用插值算法&#xff0c;通過給定的樣本點推算出一定的曲線從而推算出一些想要的值。但存在一些問題…

解決內網GitLab 社區版 15.11.13項目拉取失敗

問題描述 GitLab 社區版 發布不久&#xff0c;搭建在內網拉取項目報錯&#xff0c;可能提示 unable to access https://github.comxxxxxxxxxxx: Failed to connect to xxxxxxxxxxxxxGit clone error - Invalid argument error:14077438:SSL routines:SSL23_GET_S 15.11.13ht…

QT網絡編程之TCP

QT網絡編程之TCP TCP 編程需要用到倆個類: QTcpServer 和 QTcpSocket。 #------------------------------------------------- # # Project created by QtCreator 2023-08-

mysql截取最后一個字符之前的數據

1、mysql截取最后一個字符之前的數據 select --截取斜杠之前的數據REVERSE(SUBSTR(REVERSE(SPNH-dfg-2012) ; --截取斜杠后的數據 INSTR(REVERSE(SPNH-fg-2012),-)1))2、mysql獲取最后一個字符后的數據 select SUBSTRING_INDEX(SPNH-dfg-2012,-,-1) 3、mysql更新某個字段…

SpringBoot 該如何預防 XSS 攻擊

XSS 漏洞到底是什么&#xff0c;說實話我講不太清楚。但是可以通過遇到的現象了解一下。在前端Form表單的輸入框中&#xff0c;用戶沒有正常輸入&#xff0c;而是輸入了一段代碼&#xff1a;</input><img src1 onerroralert1> 這個正常保存沒有問題。問題出在了列表…

驅動 實現三個燈的亮滅

1、編寫LED燈的驅動&#xff0c;可以控制三個燈&#xff0c;應用程序中編寫控制燈的邏輯&#xff0c;要使用自動創建設備節點機制 head.h #ifndef __HEAD_H__ #define __HEAD_H__#define PHY_LED1_MODER 0x50006000 #define PHY_LED1_ODR 0x50006014 #define PHY_LED1_RCC 0x…

設計模式之責任鏈模式【Java實現】

責任鏈&#xff08;Chain of Resposibility&#xff09; 模式 概念 責任鏈&#xff08;chain of Resposibility&#xff09; 模式&#xff1a;為了避免請求發送者與多個請求處理者耦合在一起&#xff0c;于是將所有請求的處理者 通過前一對象記住其下一個對象的引用而連成一條…

什么是ServiceMesh(Istio一)

現在最火的后端架構無疑是微服務了&#xff0c;微服務將之前的單體應用拆分成了許多獨立的服務應用&#xff0c;每個微服務都是獨立的&#xff0c;好處自然很多&#xff0c;但是隨著應用的越來越大&#xff0c;微服務暴露出來的問題也就隨之而來了&#xff0c;微服務越來越多&a…

【Python】使用python解析普通格式的報文為someip格式報文

文章目錄 1.安裝scapy庫2.示例 1.安裝scapy庫 使用 pip 安裝 scapy 第三方庫&#xff0c;打開 cmd&#xff0c;輸入以下命令&#xff1a; pip install scapy出現如圖所示&#xff0c;表示安裝成功&#xff1a; 2.示例 要解析someip格式報文&#xff0c;需要導入someip模塊&a…

【Spring 】了解Spring AOP

目錄 一、什么是Spring AOP 二、AOP的使用場景 三、AOP組成 四、Spring AOP的實現 1、添加Spring AOP依賴 2、定義切面和切點 3、定義相關通知 五、 AOP的實現原理 1、什么是動態代理 2、 JDK代理和CGLIB代理的區別 一、什么是Spring AOP AOP&#xff08;Aspect Ori…

PLY模型格式詳解【3D】

本文介紹PLY 多邊形文件格式&#xff0c;這是一種用于存儲被描述為多邊形集合的圖形對象。 PLY文件格式的目標是提供一種簡單且易于實現但通用的格式足以適用于各種模型。 PLY有兩種子格式&#xff1a;易于入門的 ASCII 表示形式和用于緊湊存儲和快速保存和加載的二進制格式。 …

【FastColoredTextBox】C# 開源文本編輯控件

主界面截圖 使用Demos演示 FastColoredTextBox 是一個用于在 C# 程序中實現高亮語法著色、代碼編輯和文本顯示的自定義控件。它提供了許多功能&#xff0c;包括&#xff1a; 語法高亮&#xff1a;FastColoredTextBox 支持多種語言的語法高亮&#xff0c;可以根據語法規則將不同…

write javaBean error, fastjson version 1.2.76

fastjson JSON.toJSONString 報錯&#xff1a; > [0] JavaBeanSerializer.java->541: com.alibaba.fastjson.serializer.JavaBeanSerializer->write()> [1] JavaBeanSerializer.java->154: com.alibaba.fastjson.serializer.JavaBeanSerializer->write()>…

vite4+vue3+electron23.3+ts桌面應用bs端開發 打包windows、linux、max三個系統的安裝包

vite4vue3electron23.3ts桌面應用bs端開發 打包windows、linux、max三個系統的安裝包 主要包依賴 "electron-store": "^8.1.0", //全局數據狀態管理&#xff0c;可選擇性安裝"electron": "23.3.8","electron-builder": &q…

Android 使用SQLite的案例詳解

1、說明 sqlite是個輕量級的數據庫,可用于嵌入式。有時候做本地的web開發的時候,我會把sqlite作為內置數據庫,這樣便于部署,直接啟動應用即可。 這里主要是將android中的使用過程記錄一下。主要包含,數據如何初始化,在不同的activity中如何使用,以及增刪改查的實現。 …

網頁顯示攝像頭數據的方法---基于web video server

1. 背景&#xff1a; 在ros系統中有發布攝像頭的相關驅動rgb數據&#xff0c;需求端需要將rgb數據可以直接在網頁上去顯示。 問題解決&#xff1a; web_video_server功能包&#xff0c;相關鏈接&#xff1a; web_video_server - ROS Wiki 2. 下載&#xff0c;安裝和編譯&a…

Ubuntu20 ctrl+alt+T無法打開終端

事情是這樣的&#xff0c;某天改了下python版本&#xff0c;發現linux默認打開終端的快捷鍵ctrlaltT寄了&#xff0c;網上給出的都是修改快捷鍵不出意外肯定沒用 但是幸好我們是會分析的&#xff0c;我看到&#xff0c;很多回答說新增一個快捷鍵運行的命令是gnome-terminal&…

21、stm32使用LTDC驅動LCD

注&#xff1a;本文基于stm32使用FMC驅動SDRAM(IS42S32800G-6BLI)工程繼續開發 本例使用安富萊的H743XIH板子驅動LTDC點亮7寸LCD 硬件接線&#xff1a;RGB888 一、cubemx配置 1、LTDC配置 注意此引腳應于上面的硬件接線圖一致 2、配置DMA2D 3、背光引腳和觸摸引腳 4、時鐘…

在 IntelliJ IDEA 中使用 Docker 開發指南

目錄 一、IDEA安裝Docker插件 二、IDEA連接Docker 1、Docker for Windows 連接 2、SSH 連接 3、Connection successful 連接成功 三、查看Docker面板 四、使用插件生成鏡像 一、IDEA安裝Docker插件 打開 IntelliJ IDEA&#xff0c;點擊菜單欄中的 "File" -&g…