一文講清楚React Hooks

文章目錄

  • 一文講清楚React Hooks
    • 一、什么是 React Hooks?
    • 二、常用基礎 Hooks
      • 2.1 useState:狀態管理
        • 基本用法
        • 特點
      • 2.2 useEffect:副作用處理
        • 基本用法
        • 依賴數組說明
      • 2.3 useContext:上下文共享
        • 基本用法
        • 特點
    • 三、其他常用 Hooks
      • 3.1 useReducer:復雜狀態管理
      • 3.2 useCallback:記憶化回調函數
      • 3.3 useMemo:記憶化計算結果
      • 3.4 useRef:獲取DOM元素與存儲可變值
    • 四、其他實用 Hooks
    • 五、Hooks 使用規則

一文講清楚React Hooks

一、什么是 React Hooks?

React Hooks 是 React 16.8 版本引入的新特性,它允許開發者在不編寫類組件的情況下使用狀態(state)和其他 React 特性(如生命周期、上下文等)。Hooks 的出現解決了類組件中存在的代碼復用困難、邏輯分散、生命周期函數臃腫等問題,讓函數組件擁有了與類組件同等的能力。

二、常用基礎 Hooks

2.1 useState:狀態管理

`useState` 是最基礎的 Hook,用于在函數組件中添加狀態管理。

基本用法
import { useState } from 'react';function Counter() {// 聲明一個名為count的狀態變量,初始值為0// setCount是更新count的函數const [count, setCount] = useState(0);return (<div><p>你點擊了 {count}</p><button onClick={() => setCount(count + 1)}>點擊我</button></div>);
}
特點
  • 返回值:返回一個數組,第一個元素是當前狀態值,第二個元素是更新狀態的函數
  • 狀態更新
    • 調用更新函數會重新渲染組件
    • 狀態更新是異步的,多次連續更新會被合并
    • 如果新狀態依賴于舊狀態,應使用函數形式:`setCount(prevCount => prevCount + 1)`
  • 初始化:初始值只在組件首次渲染時生效

2.2 useEffect:副作用處理

`useEffect` 用于處理組件中的副作用操作,如數據獲取、訂閱、DOM 操作等,相當于類組件中的 `componentDidMount`、`componentDidUpdate` 和 `componentWillUnmount` 的組合。

基本用法
import { useState, useEffect } from 'react';function UserProfile({ userId }) {const [user, setUser] = useState(null);// 副作用函數useEffect(() => {// 獲取用戶數據(副作用操作)const fetchUser = async () => {const response = await fetch(\`/api/users/\${userId}\`);const data = await response.json();setUser(data);};fetchUser();// 清理函數(可選)return () => {// 組件卸載或userId變化時執行,用于取消訂閱、清除定時器等console.log('清理操作');};}, [userId]); // 依賴數組:只有userId變化時,才會重新執行副作用if (!user) return <div>Loading...</div>;return <div>{user.name}</div>;
}
依賴數組說明
  • 空數組 `[]`:副作用只在組件掛載時執行一次,清理函數在組件卸載時執行(類似 `componentDidMount` 和 `componentWillUnmount`)
  • 包含特定值 `[value1, value2]`:組件掛載時執行,且當數組中的值發生變化時重新執行(類似 `componentDidUpdate`)
  • 不提供依賴數組:每次組件渲染都會執行副作用

2.3 useContext:上下文共享

`useContext` 用于在函數組件中獲取上下文(Context)的值,避免了通過 props 層層傳遞數據的麻煩。

基本用法
import { createContext, useContext } from 'react';// 1. 創建上下文
const ThemeContext = createContext('light');// 2. 提供上下文值
function App() {return (<ThemeContext.Provider value="dark"><ThemedComponent /></ThemeContext.Provider>);
}// 3. 消費上下文值
function ThemedComponent() {// 使用useContext獲取上下文值const theme = useContext(ThemeContext);return <div>當前主題:{theme}</div>;
}
特點
  • 當 `ThemeContext.Provider` 的 `value` 發生變化時,所有使用 `useContext(ThemeContext)` 的組件都會重新渲染
  • `useContext` 接收一個上下文對象(由 `createContext` 創建),并返回該上下文的當前值

三、其他常用 Hooks

3.1 useReducer:復雜狀態管理

`useReducer` 是 `useState` 的替代方案,適用于處理復雜狀態邏輯或多個子值組成的狀態對象。

import { useReducer } from 'react';// 1. 定義reducer函數:接收當前狀態和動作,返回新狀態
function todoReducer(state, action) {switch (action.type) {case 'ADD_TODO':return [...state, { id: Date.now(), text: action.text, done: false }];case 'TOGGLE_TODO':return state.map(todo =>todo.id === action.id ? { ...todo, done: !todo.done } : todo);default:return state;}
}function TodoList() {// 2. 使用useReducer:接收reducer和初始狀態,返回當前狀態和dispatch函數const [todos, dispatch] = useReducer(todoReducer, []);return (<div><button onClick={() => dispatch({ type: 'ADD_TODO', text: '新任務' })}>添加任務</button><ul>{todos.map(todo => (<likey={todo.id}style={{ textDecoration: todo.done ? 'line-through' : 'none' }}onClick={() => dispatch({ type: 'TOGGLE_TODO', id: todo.id })}>{todo.text}</li>))}</ul></div>);
}

3.2 useCallback:記憶化回調函數

`useCallback` 用于記憶化回調函數,避免在每次渲染時創建新的函數實例,從而優化子組件的性能(配合 `React.memo` 使用)。

import { useCallback, useState } from 'react';function Parent() {const [count, setCount] = useState(0);// 記憶化回調函數:只有當依賴項變化時,才會創建新的函數const handleClick = useCallback(() => {console.log('點擊事件');}, []); // 空依賴數組:函數只會被創建一次return (<div><Child onClick={handleClick} /><button onClick={() => setCount(count + 1)}>計數:{count}</button></div>);
}// 使用React.memo優化子組件,避免不必要的重渲染
const Child = React.memo(({ onClick }) => {console.log('Child 渲染');return <button onClick={onClick}>點擊我</button>;
});

3.3 useMemo:記憶化計算結果

`useMemo` 用于記憶化計算結果,避免在每次渲染時重復執行昂貴的計算。

import { useMemo, useState } from 'react';function ExpensiveCalculation({ numbers }) {// 記憶化計算結果:只有當numbers變化時,才會重新計算const sum = useMemo(() => {console.log('執行計算');return numbers.reduce((acc, num) => acc + num, 0);}, [numbers]); // 依賴數組return <div>總和:{sum}</div>;
}function App() {const [count, setCount] = useState(0);const [numbers] = useState([1, 2, 3, 4, 5]);return (<div><ExpensiveCalculation numbers={numbers} /><button onClick={() => setCount(count + 1)}>計數:{count}</button></div>);
}

3.4 useRef:獲取DOM元素與存儲可變值

`useRef` 主要有兩個用途:獲取DOM元素引用和存儲不需要引起重渲染的可變值。

import { useRef, useState, useEffect } from 'react';function TextInputWithFocusButton() {// 1. 獲取DOM元素引用const inputEl = useRef(null);// 2. 存儲可變值(不會引起重渲染)const renderCount = useRef(0);const [text, setText] = useState('');useEffect(() => {renderCount.current += 1; // 修改ref的值不會觸發重渲染});const focusInput = () => {// 通過current屬性訪問DOM元素inputEl.current.focus();};return (<div><inputref={inputEl}value={text}onChange={(e) => setText(e.target.value)}/><button onClick={focusInput}>聚焦輸入框</button><p>渲染次數:{renderCount.current}</p></div>);
}

四、其他實用 Hooks

Hook用途說明
`useImperativeHandle`自定義暴露給父組件的實例值,配合 `forwardRef` 使用
`useLayoutEffect`與 `useEffect` 類似,但會在DOM更新后同步執行,可能阻塞瀏覽器繪制
`useDebugValue`在React DevTools中為自定義Hook添加標簽,便于調試

五、Hooks 使用規則

為了確保 React 能夠正確識別和管理 Hooks,必須遵守以下規則:

  1. 只能在函數組件或自定義 Hook 的頂層調用 Hooks
    • 不能在條件語句、循環、嵌套函數中調用 Hooks
    • 錯誤示例:
     function MyComponent() {if (condition) {const [count, setCount] = useState(0); // ? 不能在條件中調用}// ...}```

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

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

相關文章

Apache http 強制 https

1. 修改一下文件配置 sudo nano /etc/apache2/sites-enabled/000-default.conf<VirtualHost *:80>ServerName hongweizhu.comServerAlias www.hongweizhu.comServerAdmin webmasterlocalhostDocumentRoot /var/www/html# 強制重定向到HTTPSRewriteEngine OnRewriteCond …

【讀代碼】GLM-4.1V-Thinking:開源多模態推理模型的創新實踐

一、基本介紹 1.1 項目背景 GLM-4.1V-Thinking是清華大學KEG實驗室推出的新一代開源視覺語言模型,基于GLM-4-9B-0414基礎模型構建。該項目通過引入"思維范式"和強化學習課程采樣(RLCS)技術,顯著提升了模型在復雜任務中的推理能力。其創新點包括: 64k超長上下文…

從代碼生成到智能運維的革命性變革

AI大模型重塑軟件開發&#xff1a;從代碼生成到智能運維的革命性變革 希望對大家有一定的幫助&#xff0c;進行參考 目錄AI大模型重塑軟件開發&#xff1a;從代碼生成到智能運維的革命性變革 希望對大家有一定的幫助&#xff0c;進行參考一、范式轉移&#xff1a;軟件開發進入&…

豆包編寫Java程序小試

今天下載了一本第四版電氣工程師手冊&#xff0c;非常棒的一本書&#xff0c;在給PDF添加目錄的時候&#xff0c;由于目錄有將近60頁&#xff0c;使用老馬開發的PdgCntEditor有點卡頓&#xff0c;不過補充下&#xff0c;老馬這個PdgCntEditor還是非常好的。所以我決定用Java編一…

SpringBoot整合騰訊云新一代行為驗證碼

一 產品介紹 騰訊云官方介紹鏈接 騰訊云新一代行為驗證碼&#xff08;Captcha&#xff09;&#xff0c;基于十道安全防護策略&#xff0c;為網頁、App、小程序開發者打造立體、全面的人機驗證。在保護注冊登錄、活動秒殺、點贊發帖、數據保護等各大場景下業務安全的同時&…

SenseGlove新一代外骨骼力反饋手套Rembrand來襲!亞毫米級手部動捕+指尖觸覺力采集+5Dof主動力反饋多模態

在遠程機器人操作領域&#xff0c;精準的觸覺感知與靈活的動作控制始終是核心需求。SenseGlove 新推出的 Rembrandt 力反饋外骨骼數據手套&#xff0c;以先進技術為支撐&#xff0c;為遠程操控人形機器人手部提供了無縫解決方案&#xff0c;讓操作更精準、更高效。值得一提的是…

Linux 信號機制:操作系統的“緊急電話”系統

想象一下&#xff0c;你正在電腦前專心工作&#xff0c;突然手機響了——這是一個通知&#xff0c;要求你立即處理一件新事情&#xff08;比如接電話&#xff09;。 Linux 系統中的信號&#xff08;Signal&#xff09;?? 機制&#xff0c;本質上就是操作系統內核或進程之間用…

論文略讀:Prefix-Tuning: Optimizing Continuous Prompts for Generation

2021 ACL固定預訓練LM&#xff0c;為LM添加可訓練&#xff0c;任務特定的前綴這樣就可以為不同任務保存不同的前綴這種前綴可以看成連續可微的soft prompt&#xff0c;相比于離散的token&#xff0c;更好優化&#xff0c;效果更好訓練的時候只需要更新prefix部分的參數&#xf…

CSS基礎選擇器、文本屬性、引入方式及Chorme調試工具

CSS基礎 1.1 CSS簡介 CSS 是層疊樣式表 ( Cascading Style Sheets ) 的簡稱. 有時我們也會稱之為 CSS 樣式表或級聯樣式表。 CSS 是也是一種標記語言 CSS 主要用于設置 HTML 頁面中的文本內容&#xff08;字體、大小、對齊方式等&#xff09;、圖片的外形&#xff08;寬高、邊…

RabbitMQ 高級特性之事務

1. 簡介與 MySQL、Redis 一樣&#xff0c;RabbitMQ 也支持事務。事務中的消息&#xff0c;要么全都發送成功&#xff0c;要么全部發送失敗&#xff0c;不會出現一部分成功一部分失敗的情況。2. 使用事務發送消息spring 中使用 RabbitMQ 開啟事務需要兩步&#xff1a;第一步&…

iframe 的同源限制與反爬機制的沖突

一、事件背景A域名接入了動態防護&#xff08;Bot 防護、反爬蟲機制&#xff09;&#xff0c;同時第三方業務B域名通過內嵌iframe的方式調用了A域名下的一個鏈接。二、動態防護介紹&#xff1a;動態防護&#xff08;也稱為 Bot 防護、反爬蟲機制&#xff09;是網站為了防止自動…

Rust 的 Copy 語義:深入淺出指南

在 Rust 中&#xff0c;Copy 是一個關鍵的特性&#xff0c;它定義了類型的復制行為。理解 Copy 語義對于掌握 Rust 的所有權系統和編寫高效代碼至關重要。一、核心概念&#xff1a;Copy vs Move特性Copy 類型非 Copy 類型 (Move)賦值行為按位復制 (bitwise copy)所有權轉移 (ow…

Qt的信號與槽(二)

Qt的信號與槽&#xff08;二&#xff09;1.自定義槽2.通過圖形化界面來生成自定義槽3.自定義信號3.信號和槽帶參數4.參數數量5.connect函數的設計&#x1f31f;hello&#xff0c;各位讀者大大們你們好呀&#x1f31f;&#x1f31f; &#x1f680;&#x1f680;系列專欄&#xf…

Java研學-MongoDB(三)

三 文檔相關 7 文檔統計查詢① 語法&#xff1a; // 精確統計文檔數 慢 準 dahuang> db.xiaohuang.countDocuments({條件}) 4 // 粗略統計文檔數 快 大致準 dahuang> db.xiaohuang.estimatedDocumentCount({條件}) 4② 例子&#xff1a; // 精確統計文檔數 name為奔波兒灞…

TCP協議格式與連接釋放

TCP報文段格式 TCP雖然是面向字節流的&#xff0c;但TCP傳送帶數據單元確是報文段。TCP報文段分為首部和數據段部分&#xff0c;而TCP的全部功能體現在它在首部中各字段的作用。因此&#xff0c;只有弄清TCP首部各字段的作用才能掌握TCP的工作原理。 TCP報文段首部的前20字節是…

CSS05:結構偽類選擇器和屬性選擇器

結構偽類選擇器 /*ul的第一個子元素*/ ul li:first-child{background: #0af6f6; }/*ul的最后一個子元素*/ ul li:last-child{background: #d27bf3; } /*選中p1&#xff1a;定位到父元素&#xff0c;選擇當前的第一個元素 選擇當前p元素的父級元素&#xff0c;選中父級元素的第…

使用策略模式 + 自動注冊機制來構建旅游點評系統的搜索模塊

? 目標&#xff1a; 搜索模塊支持不同內容類型&#xff08;攻略、達人、游記等&#xff09;每種搜索邏輯用一個策略類表示自動注冊&#xff08;基于注解 Spring 容器&#xff09;新增搜索類型時&#xff0c;只需添加一個類 一個注解&#xff0c;無需改工廠、注冊表等&#x…

第八十九篇 大數據開發中的數據算法:貪心策略 - 生活中的“精打細算”藝術

在資源有限的世界里&#xff0c;貪心算法教會我們&#xff1a;局部最優的累積&#xff0c;往往是通往全局最高效的捷徑。本文通過3個生活化場景原創圖表&#xff0c;揭示大數據開發中最實用的優化策略。目錄一、貪心算法核心思想&#xff1a;當下即最優二、三大核心應用場景詳解…

【論文閱讀】Dynamic Few-Shot Visual Learning without Forgetting

系統概述如下: (a) 一個基于卷積神經網絡(ConvNet)的識別模型,該模型包含特征提取器和分類器; (b) 一個少樣本分類權重生成器。這兩個組件都是在一組基礎類別上訓練的,我們為這些類別準備了大量訓練數據。在測試階段,權重生成器會接收少量新類別的訓練數據以及基礎類別的…

HTML應用指南:利用GET請求獲取全國山姆門店位置信息

山姆會員店作為全球知名的零售品牌&#xff0c;自進入中國市場以來&#xff0c;始終致力于為消費者提供高品質商品與便捷的購物體驗。隨著新零售業態的快速發展&#xff0c;門店位置信息的獲取變得愈發重要。品牌通過不斷拓展門店網絡&#xff0c;目前已覆蓋多個一、二線城市&a…