React hooks API詳情

来源: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

usecontext React 16.3本中新引入的一個特性,它可以讓組件之間共用數據十分方便。它屬於 React Context API(上下文API),可以讓組件層級之間自由傳遞數據,而使用Context API可以極大地提高組件之間的可復用性。
使用 useContext以使組件樹中的任何組件訪問到 cntext值,無論它是何種層級的,而且更方便的是,不需要利用props行傳遞,而只需要一行代碼即可

下麵案例是同一組件下多個 子組件的上下文通訊

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

const ThemeContext = createContext('light')
// 父組件
function Test() {
  return (
    <ThemeContext.Provider value="dark">
      <Toolbar theme="dark" />
    </ThemeContext.Provider>
  )
}
// 子組件
function Toolbar(props) {
  return (
    // 中間的組件再也不必指明往下傳遞 theme 了。
    <div>
      <Button />
    </div>
  )
}
// 子組件中的子組件
function Button() {
  // 指定 contextType 讀取當前的 themecontext。
  // React 會往上找到最近的 theme Provider,然後使用它的值。
  // 在這個例子中,當前的 theme 值為 “dark”。
  const theme = useContext(ThemeContext)
  return <button>{ theme }</button>
}

 

垮文件使用usecontext 進行通訊

 父組件

import React, { useState, createContext } from 'react'
import Counter from './Counter'
 
export const countContext = createContext()
 
export default function Example4() {
    const [count, setCount] = useState(0)
    return (
        <div>
            <p>你點擊了{count}次</p>
            <button onClick={()=>{setCount(count+1)}}>點擊</button>
            <countContext.Provider value={count}>
                <Counter />
            </countContext.Provider>
        </div>
    )
}

子組件

import React, { useContext } from 'react'
import { countContext } from './Example4'
 
function Counter() {
    let count = useContext(countContext)
    return (
        <div>
            <h2>{count}</h2>
        </div>
    )
}
 
export default Counter

 

 這樣在多級組件使用就減少使用redux,useContext確實好用,起碼跨級傳遞數據不用那麼麻煩了

 

 完結,有不足歡迎補充。

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

-Advertisement-
Play Games
更多相關文章
  • 一、系統資料庫 MySQL資料庫安裝完成後,自帶了四個資料庫: mysql資料庫:存儲MySQL伺服器正常運行所需要的各種信息如時區、主從、用戶、許可權等 infomation_schema:提供了訪問資料庫元數據的各種表和視圖,包含資料庫、表、欄位類型及訪問許可權等 performance_schem ...
  • 現象 最近收到一個慢sql工單,慢sql大概是這樣:“select xxx from tabel where type = 1”。 咦,type欄位明明有索引啊,為啥是慢sql呢? 原因 通過執行explain,發現實際上資料庫執行了全表掃描,從而被系統判定為慢sql。這時有一定開發經驗的同事會說: ...
  • 對於iOS開發者而言,CocoaPods並不陌生,通過pod相關的命令操作,就可以很方便的將項目中用到的三方依賴庫資源集成到項目環境中,大大的提升了開發的效率。CocoaPods作為iOS項目的包管理工具,它在命令行背後做了什麼操作?而又是通過什麼樣的方式將命令指令聲明出來供我們使用的?這些實現的背... ...
  • 這裡給大家分享我在實際生活中總結出來的一些知識,希望對大家有所幫助 一.SDK引入 這裡提供兩套引入流程,一套是vue2.0及其他h5項目,一套是vue3.0的引入流程 不懂的也可以看我之前的一篇詳細流程 記錄--微信調用jssdk全流程詳解 1.js引入 直接在你的頁面里引入js文件就行 <scr ...
  • 上半年vercel 推出了nextjs13 這個大版本,剛好最近有個c端的項目,所以就用了這個框架來寫,技術體系基本也是文檔提到的 tailwindcss + ts + swr + ssr ,總的來開發體驗還可以,不管是打包速度、文檔、錯誤信息提示目前都還滿意,只不過目前nextjs13 中文資料有 ...
  • 在JavaScript開發的現代世界中,有許多不同的前端框架可供我們用來編寫應用程式,從舊的框架如Backbone.js到較新的Angular、React和Vue等。這些框架通常使用模型視圖控制器(MVC)設計模式或其變體之一,例如模型視圖表現器(MVP)或模型視圖視圖模型(MVVM)。當將這組模式 ...
  • 本文是由最近做的一個項目有感而發,因為之前做了一些技術棧的統一,為了用ant Design的pro-table,PC統一使用react,但是我們有一些老的項目是vue的,本次新頁面較多,老頁面的改動較少,除此之外老項目想換菜單,因此我們想藉助本次機會用react開發,經過了幾番思考,發現本次很適合用... ...
  • web前端JavaScript交互 點擊事件 意義: JavaScript中的點擊事件是指當用戶在頁面上點擊某個元素時觸發的事件。這個事件可以用於執行各種操作,如改變元素的樣式、修改頁面內容等。這是Web應用程式中最常用 的交互方式之一,允許用戶與網頁進行交互,提高用戶體驗。 案例: 隨機點名器 知 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...