React hooks 大全詳情

来源:https://www.cnblogs.com/Allen-project/archive/2023/09/19/17712607.html
-Advertisement-
Play Games

import React, { useEffect, useState } from 'react'; hook 是react 16.8的新增特性 ,他可以讓你不在編寫class的情況下shiystate以及react的特性 Hooks的出現,首先解決了以下問題: 告別了令人疑惑的生命周期 告別類組 ...


import React, { useEffect, useState } from 'react';

hook 是react 16.8的新增特性 ,他可以讓你不在編寫class的情況下shiystate以及react的特性 Hooks的出現,首先解決了以下問題:
  1. 告別了令人疑惑的生命周期
  2. 告別類組件中煩人的this
  3. 告別繁重的類組件,回歸到了熟悉的函數組件
react 整個思想上面的轉變,從“面向對象”的思想轉為“函數式編程”,所以你會突然發現會多了一些新概念 比如:純函數,副作用,柯里化,高階函數等概念  

useState 

 

 1.基礎使用

import { useState } from 'react'
function App() {
    // 參數:狀態初始值比如,傳入 0 表示該狀態的初始值為 0
    // 返回值:數組,包含兩個值:1 狀態值(state) 2 修改該狀態的函數(setState)
    const [count, setCount] = useState(0);
    //   修改count內容
    const modifyEvent = () => {
        setCount(count + 1)
    }
    return (
        <button onClick={() => modifyEvent()}>{count}</button>
    )
}
export default App

 

 2.狀態的讀取和修改執行流程與邏輯

  讀取狀態:該方式提供的狀態,是函數內部的局部變數,可以在函數內的任意位置使用   修改狀態:

    1.setCount是一個函數,參數表示最新的狀態值

    2.調用該函數後,將使用新值替換舊值

    3.修改狀態後,由於狀態發生變化,會引起試圖變化 註意

  事項:修改狀態的時候,一定要使用新的狀態替換舊的狀態,不能直接修改舊的狀態,尤其是引用類型

 

3. 組件的更新過程

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

  1.組件第一次渲染

  • 從頭開始執行該組件中的代碼邏輯
  • 調用 useState(0) 將傳入的參數作為狀態初始值,即:0
  • 渲染組件,此時,獲取到的狀態 count 值為: 0

  2.組件第二次渲染

  • 點擊按鈕,調用 setCount(count + 1) 修改狀態,因為狀態發生改變,所以,該組件會重新渲染
  • 組件重新渲染時,會再次執行該組件中的代碼邏輯
  • 再次調用 useState(0) ,此時 React 內部會拿到最新的狀態值而非初始值,比如,該案例中最新的狀態值為 1
  • 再次渲染組件,此時,獲取到的狀態 count 值為:1
註:useState 的初始值(參數)只會在組件第一次渲染時生效。也就是說,以後的每次渲染,useState 獲取到都是最新的狀態值,React 組件會記住每次最新的狀態值 
import { useState } from 'react'
 
function App() {
  const [count, setCount] = useState(0)
  // 在這裡可以進行列印
  console.log(count,'渲染了')
  return (
    <button onClick={() => { setCount(count + 1) }}>{count}</button>
  )
}
export default App

 4.使用規則

  1.useState 函數可以執行多次,每次執行互相獨立,每調用一次為函數組件提供一個狀態
function List(){
  // 以字元串為初始值
  const [name, setName] = useState('cp')
  // 以數組為初始值
  const [list,setList] = useState([])
}

  2.useState 註意事項

  • 只能出現在函數組件或者其他hook函數中
  • 能嵌套在if/for/其它函數中(react按照hooks的調用順序識別每一個hook)

 

useEffect

1.理解函數副作用

   副作用是相對於主作用來說的,一個函數除了主作用,其他的作用就是副作用。對於 React 組件來說,主作用就是根據數據(state/props)渲染 UI,除此之外都是副作用(比如,手動修改 DOM)   常見的副作用:
  • 數據請求 ajax發送
  • 手動修改dom
  • localstorage操作
  useEffect函數的作用就是為react函數組件提供副作用處理的數據和邏輯,從而修改UI和用戶交互等一種方式。  

2. 基礎使用

下麵案例說明,函數組件儲存了當前state所有狀態,函數初次就會觸發他們兩個的載入,另外當某一個發生改變了 useEffect和函數都會被重新執行載入

import { useEffect, useState } from 'react'
 
function App() {
  const [count, setCount] = useState(0)
 
  useEffect(()=>{
    // 修改了dom數據後 userffect函數被副作用重新執行
    console.log('執行了副作用函數')
  });
    // 函數組件也會被重新執行   
  console.log('函數組件被重新執行了')
  return (
    <button onClick={() => { setCount(count + 1) }}>{count}</button>
  )
}
 
export default App

 

3.useEffect依賴項和控制執行的時機

由於 組件首次渲染執行一次,以及不管是哪個狀態更改引起組件更新時都會重新執行   添加空數組依賴
import { useEffect, useState } from 'react'
function App() {
  const [count, setCount] = useState(0)
  useEffect(()=>{
    // 修改了dom數據後 userffect函數不會在被觸發,只有首次載入函數才會執行一次
    console.log('執行了副作用函數')
  },[]);
    //修改了dom數據後 函數組件會被重新執行   
  console.log('函數組件被重新執行了')
  return (
    <button onClick={() => { setCount(count + 1) }}>{count}</button>
  )
}
export default App

添加特定項作為依賴

副作用函數在首次渲染時執行,在依賴項發生變化時重新執行

給useEffect添加特定的依賴項,當這個依賴性的state發生改變,useEffect與函數組件都會重新渲染被執行,由於第二個參數是依賴項所以是數組可以添加多個依賴項

沒有useEffect添加的特定的依賴項,就不會觸發useEffect函數,只會觸發組件的渲染函數

function App() {  
    const [count, setCount] = useState(0)  
    const [name, setName] = useState('zs') 
    
    useEffect(() => {    
        console.log('副作用執行了')  
    }, [count])  
    console.log('組件被執行了')
    return (    
        <>      
         <button onClick={() => { setCount(count + 1) }}>{count}</button>      
         <button onClick={() => { setName('cp') }}>{name}</button>    
        </>  
    )
}

清理副作用

 
function App() {
    const [count, setCount] = useState(0)
    const [name, setName] = useState('zs')

    useEffect(() => {
        console.log('副作用執行了')
        return () => {
            alert(1)
            console.log('執行了清楚副作用,組件卸載的時候執行')
        }
    }, [count])
    console.log('組件被執行了')
    return (
        <>
            <button onClick={() => { setCount(count + 1) }}>{count}</button>
            <button onClick={() => { setName('cp') }}>{name}</button>
        </>
    )
}

 

另外一般一個 useEffect 只用來處理一個功能,有多個功能時,建議使用多個 useEffect  

useMemo(性能優化)

解決函數組件的性能問題,比如子組件重覆執行問題,每次渲染都進行高開銷的計算

// 子組件
function Sub(props) {
    console.log("Sub render");
    let { number, onClick } = props
    return (
        <button onClick={onClick}>{number}</button>
    )
}
// 父組件
function Test() {
    let [value, setValue] = useState('')
    let [number, setNumber] = useState(0)
    const addClick = () => setNumber(number + 1)
    return <>
        <input type="text" value={value} onChange={(e) => setValue(e.target.value)} />
        <Sub number={number} onClick={addClick} />
    </>
}

export default Test;

子組件依賴的只有number ,理想情況下只希望number變化時觸發子組件重新渲染

但實際是在輸入框內的值發生變化,子組件也會重新渲染 如果子組件的邏輯較複雜,就是無意義的大量計算,浪費資源

// 子組件
function Sub(props) {
    console.log("Sub render");
    let { number, onClick } = props
    return (
        <button onClick={onClick}>{number}</button>
    )
}
// 父組件
function Test() {
    let [value, setValue] = useState('')
    let [number, setNumber] = useState(0)
    const addClick = () => setNumber(number + 1);
    // 使用useMemo記住計算後的值,只有當依賴number變數發生變化,才會重新計運算元組件內容
    const MemoSub = useMemo(
        () => <Sub data={number} onClick={addClick} />,
        [number] // 只有 number 變化才重新計算 MenoSub
      )
    return <>
        <input type="text" value={value} onChange={(e) => setValue(e.target.value)} />
        {MemoSub}
    </>
}

export default Test;

 

useCallback(性能優化)

接收兩個參數:回調函數和依賴項數組。回調函數是需要緩存的函數,依賴項數組用於確定何時需要重新創建函數實例。

當依賴項數組中的任何一個值發生變化時,useCallback 將返回一個新的函數實例,否則它將返回之前緩存的函數實例

import { useState, useCallback } from 'react';

function MyComponent() {
  const [count, setCount] = useState(0);

  // 使用 useCallback 緩存 handleClick 函數
  const handleClick = useCallback(() => {
    setCount(count + 1);
  }, [count]);

  return (
    <div>
      <p>You clicked {count} times</p>
      {/* 在按鈕上使用緩存的 handleClick 函數 */}
      <button onClick={handleClick}>Click me</button>
    </div>
  );
}

在這個例子中,我們使用 useCallback 來緩存回調函數 handleClick, 將其緩存以避免在每次重新渲染組件時創建新的函數實例。

同時,在按鈕上使用了緩存的 handleClick 函數,以確保點擊按鈕時調用的是緩存的函數實例。我們還將 count 添加到依賴項數組中,以確保每當 count 發生變化時,handleClick 都會被重新創建。

useCallback 和 useMomeo 的區別

1.useCallback 和 useMemo 都是用於性能優化的 React 鉤子函數,它們都可以避免不必要的重新計算或重新渲染。雖然它們看起來很相似,但它們有幾個重要的區別。

2.首先,useCallback 返回一個緩存的回調函數,而 useMemo 返回一個緩存的值。這意味著 useCallback 的主要作用是為一個函數創建緩存,而 useMemo 的主要作用是緩存一個值

3.最後,它們的使用場景也不同。useCallback 適用於優化回調函數,避免不必要的重新渲染,並傳遞給子組件。而 useMemo 適用於優化計算開銷較大的值,如大型數組或對象的計算

 

useRef

useRef 可以緩存所有數據類型,更新的數據不會隨著組件的重新渲染而重置,會一直保持最新狀態的內容,

但是保存的數據類型 無法在ui渲染頁面上使用,只能作為一個狀態進行儲存

也可以綁定給一個元素標簽獲取dom進行操作

function Test() {
    /* 保存 DOM */
    const inputEl = useRef()
    const onClick = () => {
        console.log(inputEl); // 對象類型,只有一個 current 屬性指向指定DOM
        inputEl.current.innerHTML = '2asdasd sd阿薩德'
    }

    return <div>
        <div ref={inputEl}></div>
        <button onClick={onClick}>click me!!!</button>
        <br />
    </div>
}

 

useContext

 

 

 

 

 

 

 

 

 

 

 

 

         
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、InnoDB行格式 行格式 緊湊的存儲特性 增強的可變長度列存儲 大型索引鍵首碼支持 壓縮支持 支持的表空間類型 REDUNDANT N N N N system, file-per-table, general COMPACT Y N N N system, file-per-table, g ...
  • 前言 ProxySQL ProxySQL 是基於 MySQL 的一款開源的中間件的產品,是一個靈活的 MySQL 代理層,可以實現讀寫分離,支持 Query 路由功能,支持動態指定某個 SQL 進行緩存,支持動態載入(無需重啟 ProxySQL 服務),故障切換和一些 SQL 的過濾功能。 Grea ...
  • 查詢SQL語句執行頻率 查詢 mysql 服務啟動時長 SHOW STATUS LIKE 'uptime'; 下列輸出表示服務啟動了276324秒 + + + | Variable_name | Value | + + + | Uptime | 276324 | + + + 查詢全局SQL執行的頻率 ...
  • 一、前言 MySQL的服務實現通過後臺多個線程、記憶體池、文件交互來實現對外服務的,不同線程實現不同的資源操作,各個線程相互協助,共同來完成資料庫的服務。MySQL常用的後臺線程概括如下,分為Master Thread,IO Thread,Purge Thread,Page Cleaner Threa ...
  • 眾所周知,在現實世界中,每一個資源都有其提供能力的最大上限,當單一資源達到最大上限後就得讓多個資源同時提供其能力來滿足使用方的需求。同理,在電腦世界中,單一資料庫資源不能滿足使用需求時,我們也會考慮使用多個資料庫同時提供服務來滿足需求。當使用了多個資料庫來提供服務時,最為關鍵的點是如何讓每一個數據 ...
  • web前端JavaScript交互 點擊事件 意義: JavaScript中的點擊事件是指當用戶在頁面上點擊某個元素時觸發的事件。這個事件可以用於執行各種操作,如改變元素的樣式、修改頁面內容等。這是Web應用程式中最常用 的交互方式之一,允許用戶與網頁進行交互,提高用戶體驗。 案例: 隨機點名器 知 ...
  • 工作中經常遇到按照指定格式的時間進行展示。可參考以下腳本邏輯滿足需求 Date.prototype.PtTimeByFormat = function (fmt){ var o = { "M+": this.getMonth() + 1, //月份 "d+": this.getDate(), //日 ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 前言 可選鏈運算符(?.),大家都很熟悉了,直接看個例子: const result = obj?.a?.b?.c?.d 很簡單例子,上面代碼?前面的屬性如果是空值(null或undefined),則result值是undefined,反 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...