【React】精選10題

1.React Hooks帶來了什么便利?

React Hooks是React16.8版本中引入的新特性,它帶來了許多便利。

  1. 更簡單的狀態管理
    使用useState Hook可以在函數組件中方便地管理狀態,避免了使用類組件時需要繼承React.Component的繁瑣操作。

  2. 避免使用類組件:函數式組件的書寫方式更加簡單、直觀,避免了類組件中this指針的混亂問題。

  3. 更少的重復代碼:使用useEffect Hook可以方便地實現數據獲取、DOM操作等副作用相關的操作,避免了在不同的生命周期函數中重復編寫相似的代碼。

  4. 更好的代碼復用:自定義Hook可以將一些可復用的邏輯封裝起來,方便在不同的組件中復用。

  5. 更好的邏輯分離:使用useContext、useReducer和自定義Hook等可以幫助將邏輯分離到獨立的模塊中,提高代碼的可維護性和可擴展性。

總之,React Hooks帶來了更加簡單、直觀、高效的編程方式,可以讓開發者更加專注于組件的邏輯實現。使得React的函數組件也具備了類組件的一些特性。

2. 列舉幾個常見的 Hook?

  1. useState Hook:用于在函數組件中管理狀態,可以通過調用useState Hook來聲明一個狀態變量和更新函數,例如:

    const [count, setCount] = useState(0);
    
  2. useEffect Hook:用于在函數組件中處理副作用,可以傳入一個回調函數和一個依賴數組,例如:

    useEffect(() => {// 處理副作用
    }, [dependency]);
    
  3. useContext Hook:用于在函數組件中訪問React Context中的值,例如:

3.1. 在MyContext.js中定義MyContext上下文對象:

import { createContext } from 'react';const MyContext = createContext();
export default MyContext;

3.2. 在App.js中使用MyContext.Provider包裹Child組件,傳遞要共享的數據

import MyContext from './MyContext';
import Child from './Child';function App() {const data = 'hello world';return (<MyContext.Provider value={data}><Child /></MyContext.Provider>);
}

3.3 在Child.js中使用useContext函數獲取到MyContext傳遞的值:

import MyContext from './MyContext';function Child() {const data = useContext(MyContext);return <h1>{data}</h1>;
}export default Child;
  1. useReducer Hook:用于在函數組件中管理復雜狀態,可以將一個reducer函數和初始狀態傳入useReducer Hook,返回一個狀態和派發更新的函數,例如:
import React, { useReducer } from 'react';const initialState = { count: 0 };function reducer(state, action) {switch (action.type) {case 'increment':return { count: state.count + 1 };case 'decrement':return { count: state.count - 1 };default:throw new Error();}
}function Counter() {const [state, dispatch] = useReducer(reducer, initialState);return (<div>Count: {state.count}<button onClick={() => dispatch({ type: 'increment' })}>+</button><button onClick={() => dispatch({ type: 'decrement' })}>-</button></div>);
}
  1. useCallback Hook:用于在函數組件中緩存回調函數,避免因為每次渲染都重新創建回調函數導致子組件重復渲染,例如:
import React, { useState, useCallback } from 'react';function MyComponent() {const [count, setCount] = useState(0);const handleClick = useCallback(() => {setCount(count + 1);}, [count]);return (<div><p>Count: {count}</p><button onClick={handleClick}>Increment Count</button></div>);
}

在這個示例中,我們使用了 useCallback Hook 緩存了 handleClick 函數。handleClick 會在點擊按鈕時被調用,并將 count 的值加 1。我們將 count 作為依賴數組傳入 useCallback 中,確保每次 count 發生變化時,handleClick 函數都會被更新。

使用 useCallback Hook 可以避免在每次渲染時都創建新的函數引用,從而提高性能。這對于傳遞給子組件的回調函數尤其有用,確保子組件不會不必要地重新渲染。同時,也可以使用 useMemo Hook 緩存計算結果,從而進一步提高性能。

  1. useMemo Hook:提供的一個 Hook,用于緩存計算結果,避免在每次渲染時都重新計算,從而提高性能。它接收一個計算函數和一個依賴數組作為參數,返回緩存的計算結果。
    例如:
import React, { useMemo, useState } from 'react';function MyComponent() {const [count, setCount] = useState(0);const expensiveCalculation = useMemo(() => {console.log('Calculating...');let result = 0;for (let i = 0; i < count * 1000000; i++) {result += i;}return result;}, [count]);return (<div><p>Count: {count}</p><p>Expensive Calculation: {expensiveCalculation}</p><button onClick={() => setCount(count + 1)}>Increment Count</button></div>);
}
  1. useRef: 獲取組件的真實節點或存儲一些不常更新的數據,這些數據不受組件重新渲染影響。
  • 獲取真實節點
const ref = useRef(null)
<div ref ={ref} > </div>
// 設置真實節點屬性 .current為固定用法
ref.current.style.color = 'red'
  • 存儲數據
const ref_obj = useRef({name:'icy',age:23
})
// 改變存儲的數據
ref.obj.current.name = 'icy-godlike'

還有其他常用的Hook函數,如useImperativeHandle、useLayoutEffect等,開發者可以根據具體的需求選擇不同的Hook函數。

3. 使用React Hooks有什么優勢?

簡化組件的復雜度:React Hooks可以幫助組件更加簡潔明了,避免類組件中的一些復雜的生命周期函數。

更容易共享邏輯:React Hooks可以將組件中的狀態和邏輯提取出來,通過自定義Hook在不同的組件中進行共享。

更容易測試:React Hooks可以將狀態和邏輯的處理分離,使得測試變得更容易。

更好的性能:React Hooks可以避免類組件中因為響應式更新造成的額外渲染,從而提高應用的性能。

更快的開發速度:React Hooks能夠幫助開發者更快地構建出復雜的UI組件,從而提高開發效率。

4. 簡單介紹下React中diff算法?

在 React 中,當組件的狀態發生變化時,React 會重新渲染組件。為了提高渲染效率,React 會使用一種叫做 diff 算法(也稱為協調算法)來計算出哪些部分需要更新,哪些部分不需要更新。

簡單來說,diff 算法就是比較兩棵樹的差異,然后將差異應用到真實的 DOM 樹上,從而實現只更新必要的部分,避免全量更新。

React 中的 diff 算法具體實現如下:

對比兩棵樹的根節點,如果類型不同,則直接替換整個節點及其子節點,不再進行進一步比較;如果類型相同,則進入下一步。

對比節點的屬性,如果發生變化,則更新節點的屬性;如果沒有變化,則進入下一步。

對比子節點,React 使用一種叫做 key 的機制來判斷哪些節點需要更新,哪些節點需要刪除,哪些節點需要新增。如果節點的 key 相同,則認為是同一節點,進行進一步比較;如果節點的 key 不同,則直接替換整個節點及其子節點,不再進行進一步比較。

對比完成后,React 會根據計算出的差異,生成一份更新計劃(也稱為變更記錄),然后根據這份更新計劃,進行 DOM 操作,將變更應用到真實的 DOM 樹上。

通過使用 diff 算法,React 可以避免全量更新,從而提高渲染效率,使得 React 在大規模數據渲染的場景下仍然能夠保持流暢的性能。

5. React中,能否直接將 props 的值復制給 state?

可以,但是應該避免這種寫法:

constructor(props) {super(props);// 不要這樣做this.state = { color: props.color };
}

只有在初始化組件狀態時才能這樣做。在組件的生命周期中,props 的值是不會自動更新到 state 中的,因此如果需要在組件運行時更新 state,需要使用setState()方法。

6. React Hooks當中的useEffect是如何區分生命周期鉤子的

useEffect 鉤子函數可以接收兩個參數,第一個參數是一個函數,稱為 effect 函數,第二個參數是一個數組,稱為依賴項數組。

在 React 中,每一個組件都有不同的生命周期鉤子,例如 componentDidMount,componentDidUpdate,componentWillUnmount 等。useEffect 鉤子函數可以在一個函數中處理這些不同的生命周期鉤子。

當使用 useEffect 鉤子函數時,React 會自動根據參數來判斷當前需要使用哪個生命周期鉤子。

當依賴項數組為空時,useEffect 鉤子函數的行為類似于 componentDidMount 和 componentWillUnmount 的結合體,即只在組件掛載時執行一次,并在組件卸載時執行清理操作。

當依賴項數組不為空時,useEffect 鉤子函數的行為類似于 componentDidUpdate,即在組件掛載時執行一次,之后每次依賴項發生變化時都會執行一次,最后在組件卸載時執行清理操作。

因此,useEffect 鉤子函數的行為會根據傳入的依賴項數組的變化而變化,從而實現了不同的生命周期鉤子的功能。

useEffect(() => {console.log('mounted'); // 依賴數組為[]時,componentDidMount | 依賴數組不為空,且發生變化時 componentDidUpdatereturn () => {console.log('willUnmount'); //  依賴數組為[]時,componentWillUnmount }}, [source]);

7. 為什么不能用數組下標來作為react組件中的key?

在 React 中,key 屬性用于標識組件在列表中的順序,并用于優化組件的重新渲染。key 必須是唯一的,并且在組件列表中始終保持不變。

不能使用數組下標作為 key 屬性是因為數組下標與組件的實際內容沒有關系。例如,如果你在一個列表中刪除第一個元素,React 將重新生成列表中所有元素的 key,因為數組下標已經改變,導致 React 需要重新渲染所有組件。

此外,使用數組下標作為 key 屬性可能會導致錯誤的渲染結果。例如,如果你有兩個組件,它們的 key 屬性分別為 0 和 1,并且你想交換它們的順序,則交換它們在數組中的位置可能會導致 key 屬性被錯誤地匹配到錯誤的組件上,從而導致渲染錯誤。

因此,為了避免以上問題,key 屬性應該是與組件的實際內容相關的唯一標識符,例如組件在數據庫或服務端的 ID。

8. React Fiber是什么?

React Fiber 是 React 16 中引入的新的協調引擎。React Fiber 是一種新的、可中斷的調度算法,可以更好地支持漸進式渲染、處理大型組件樹以及優化代碼的可維護性。

React Fiber 的主要目標是提高 React 應用程序的性能和交互性。具體來說,React Fiber 可以:

實現異步渲染,將渲染任務分割成多個小任務,并調度它們的執行順序,以提高應用程序的響應性和流暢性。
支持可中斷的渲染,允許 React 在執行長時間的計算或等待異步數據時中斷渲染,并在后臺執行其他任務,以避免應用程序的停頓或卡頓。
支持漸進式渲染,允許 React 逐步地將組件樹渲染到屏幕上,從而更快地響應用戶輸入,并提高應用程序的交互性。
改進錯誤處理和調試功能,使得開發人員可以更輕松地調試和修復錯誤。
總之,React Fiber 是 React 16 中的一個重要特性,可以顯著提高 React 應用程序的性能、交互性和可維護性。

9. 虛擬DOM一定更快嗎?

虛擬 DOM 并不一定比直接操作 DOM 更快,因為在生成虛擬 DOM 的過程中也需要進行計算和操作。但是,使用虛擬 DOM 有以下幾個優點:

減少不必要的操作:由于 React 使用了虛擬 DOM,可以將多次 DOM 操作合并為一次,從而減少了不必要的 DOM 操作,提高了性能。
避免重復渲染:React 會比較新舊虛擬 DOM 樹的差異,只更新差異部分對應的真實 DOM,避免了重復渲染整個組件,提高了性能。
跨平臺支持:虛擬 DOM 是 React 在 Web、Native 等多個平臺都可以使用的重要原因之一。
當然,在某些場景下,直接操作 DOM 也可能比使用虛擬 DOM 更快,例如非常簡單的組件或需要頻繁更新的組件。但總的來說,在大多數情況下,使用虛擬 DOM 可以提高 React 應用程序的性能和可維護性。

10. 不同版本的 React 都做過哪些優化?

React 16 引入了 Fiber 架構,以提高應用程序的性能和交互性。
React 16.3 引入了新的 Context API,以更方便地共享數據和狀態。
React 16.6 引入了 memo 和 lazy 函數,以更有效地處理組件性能和代碼分離。
React 16.8 引入了 Hooks,以更方便地處理組件之間的狀態和邏輯。
React 17 引入了新的事件系統以及一些其他的優化,例如對異常的處理方式等等。
除此之外,React 還對一些其他的細節進行了優化,例如對組件生命周期方法的改進、對 Virtual DOM 的優化、對 React Native 的優化等等。

React渲染頁面的兩個階段:

調度階段(reconciliation):在這個階段 React 會更新數據生成新的 Virtual DOM,然后通過Diff算法,快速找出需要更新的元素,放到更新隊列中去,得到新的更新隊列。
渲染階段(commit):這個階段 React 會遍歷更新隊列,將其所有的變更一次性更新到DOM上。

React 15 架構

React15架構可以分為兩層:

Reconciler(協調器)—— 負責找出變化的組件;
Renderer(渲染器)—— 負責將變化的組件渲染到頁面上;
在React15及以前,Reconciler采用遞歸的方式創建虛擬DOM,遞歸過程是不能中斷的。如果組件樹的層級很深,遞歸會占用線程很多時間,遞歸更新時間超過了16ms,用戶交互就會卡頓。

為了解決這個問題,React16將遞歸的無法中斷的更新重構為異步的可中斷更新,由于曾經用于遞歸的虛擬DOM數據結構已經無法滿足需要。于是,全新的Fiber架構應運而生。

React 16 架構

為了解決同步更新長時間占用線程導致頁面卡頓的問題,也為了探索運行時優化的更多可能,React開始重構并一直持續至今。重構的目標是實現Concurrent Mode(并發模式)。

從v15到v16,React團隊花了兩年時間將源碼架構中的Stack Reconciler重構為Fiber Reconciler。

React16架構可以分為三層:

Scheduler(調度器)—— 調度任務的優先級,高優任務優先進入Reconciler;
Reconciler(協調器)—— 負責找出變化的組件:更新工作從遞歸變成了可以中斷的循環過程。Reconciler內部采用了Fiber的架構;
Renderer(渲染器)—— 負責將變化的組件渲染到頁面上。

React 17 優化

React16的expirationTimes模型只能區分是否>=expirationTimes決定節點是否更新。React17的lanes模型可以選定一個更新區間,并且動態的向區間中增減優先級,可以處理更細粒度的更新。

Lane用二進制位表示任務的優先級,方便優先級的計算(位運算),不同優先級占用不同位置的“賽道”,而且存在批的概念,優先級越低,“賽道”越多。高優先級打斷低優先級,新建的任務需要賦予什么優先級等問題都是Lane所要解決的問題。

Concurrent Mode的目的是實現一套可中斷/恢復的更新機制。其由兩部分組成:

一套協程架構:Fiber Reconciler
基于協程架構的啟發式更新算法:控制協程架構工作方式的算法

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

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

相關文章

小紅書運營 變現方法總結(精)

大家好&#xff0c;我是網媒智星&#xff0c;今天跟大家分享一下小紅書運營方面的知識&#xff0c;怎樣利用小紅書變現&#xff1f;全篇傾情干貨輸出&#xff0c;認真學習&#xff0c;保證您收獲多多。 首先&#xff0c;讓我們來分析一下小紅書平臺的優勢。關于賣東西&#xff…

Open3D (C++) 基于擬合高差的點云地面點提取

目錄 一、算法原理1、原理概述2、參考文獻二、代碼實現三、結果展示1、原始點云2、提取結果四、相關鏈接系列文章(連載中。。。): Open3D (C++) 基于高程的點云地面點提取Open3D (C++) 基于擬合平面的點云地面點提取Open3D (C++) 基于擬合高差的點云地面點提取</

vue + less 實現動態主題換膚功能

文章目錄 前言一、前提條件1. 初始化vue項目2. 安裝插件 二、新建文件夾主題theme1.style.less文件2.model.js文件3.theme.js文件theme文件夾最終效果 三、修改vue.config.js文件四、頁面上的具體使用1. index.vue 頁面2. index.vue 頁面注意點說明3. index.vue 效果 五、在js中…

VSCode使用SSH無密碼連接Ubuntu

VSCode使用SSH無密碼連接Ubuntu 前提條件&#xff1a; 1. 能夠正常使用vscode的Remote-ssh連接Ubuntu 2. Ubuntu配置靜態ip&#xff08;否則經常需要修改Remote-ssh的配置文件里的IP&#xff09; 鏈接-> ubuntun 18.04設為靜態ip&#xff08;.net模式&#xff0c;可連接…

shell使用總結

一、語法 數據類型 字符串 如果沒有特殊說明&#xff0c;數據類型默認都是字符串。常見字符串操作有&#xff1a; 已知變量strabcabc 1、切片 echo ${str:1:3} #${varName:offset:size},分頁取子串 echo ${str:2} #${varName:offset},偏移offset個字符取至末端 echo …

加載AB包程序集,反射獲取并實例化類調用方法

加載AB包文件&#xff0c;加載bytes程序集資源&#xff0c;通過反射獲取類&#xff0c;實例化添加組件&#xff0c;調用方法 public class LoadAB : MonoBehaviour {private void Update(){if (Input.GetKeyDown(KeyCode.H)){Load();}}void Load(){string classname "ID…

如何解決docker中出現的“bash: vim: command not found”

目錄 問題描述&#xff1a; 問題解決&#xff1a; 問題描述&#xff1a; 在docker中&#xff0c;想要執行vim編輯文件&#xff0c;彈出“docker bash: vim: command not found“&#xff08;如下圖&#xff09;&#xff0c;請問該如何解決&#xff1f; 問題解決&#xff1a; …

FPGA應用學習筆記------系統復位一(同異復位)

要滿足復位恢復時間才能正常復位&#xff0c;不然會產生輸出準穩態&#xff0c;輸出邏輯錯誤 復位恢復時間只會存在復位釋放時刻&#xff0c;不會出現在確立時刻&#xff0c;則不推薦完全異步復位 完全同步復位&#xff0c;肯定是同步于時鐘滴&#xff0c;并將總是滿足時鐘條件…

研發工程師玩轉Kubernetes——就緒探針(Readiness Probe)和服務(Service)

在《研發工程師玩轉Kubernetes——啟動、存活和就緒探針》中&#xff0c;我們講了就緒探針和服務之間的特殊關系。就緒探針檢測失敗并不代表整個程序處于“非存活”狀態&#xff0c;可能只是短暫臨時的不可以提供服務&#xff0c;比如CPU階段性占滿&#xff0c;導致就緒探針檢測…

【Spring MVC】Spring MVC基于注解的程序開發

目錄 一、什么是Spring MVC 二、Spring MVC項目的創建和使用 1、實現客戶端和服務器端之間的連接 1.1、RequsestMapping注解 1.2、RequestMapper的簡單使用 1.3、使用GetMapping和POSTMapping注解來實現HTTP連接 三、獲取參數 1、實現獲取單個參數 2、實現獲取對象 3…

解決ubantu驅動掉了的問題

這里寫自定義目錄標題 解決ubuntu驅動掉了的問題 解決ubuntu驅動掉了的問題 首先確定是否有驅動&#xff1a; ls /usr/src | grep nvidia若有&#xff0c;則大概率是驅動版本與內核版本對應不上&#xff0c;則把內核版本切換為初始版本即可。參照&#xff1a;https://blog.cs…

書寫自動智慧:探索Python文本分類器的開發與應用:支持二分類、多分類、多標簽分類、多層級分類和Kmeans聚類

書寫自動智慧&#xff1a;探索Python文本分類器的開發與應用&#xff1a;支持二分類、多分類、多標簽分類、多層級分類和Kmeans聚類 文本分類器&#xff0c;提供多種文本分類和聚類算法&#xff0c;支持句子和文檔級的文本分類任務&#xff0c;支持二分類、多分類、多標簽分類…

nodejs+vue+elementui+express智慧社區小區物業管理系統的設計與實現_2p760

開發語言 node.js 框架&#xff1a;Express 前端:Vue.js 數據庫&#xff1a;mysql 數據庫工具&#xff1a;Navicat 開發軟件&#xff1a;VScode 前端nodejsvueelementuiexpress vue的文件結構其實就是一個index.html 中間的內容&#xff0c;用的是vue&#xff0c;但最終都會轉…

OpenCV圖像處理——形態學操作

目錄 連通性形態學操作腐蝕和膨脹開閉運算禮帽和黑帽 連通性 形態學操作 形態學轉換是基于圖像形狀的一些簡單操作。它通常在二進制圖像上執行。腐蝕和膨脹時兩個基本的形態學運算符。然后它的變體形式如開運算&#xff0c;閉運算&#xff0c;禮帽黑帽等 腐蝕和膨脹 cv.erode…

費曼學習法

費曼學習法 費曼學習法&#xff08;Feynman Technique&#xff09;是一種學習和理解復雜概念的方法&#xff0c;以理查德費曼&#xff08;Richard Feynman&#xff09;這位著名的理論物理學家命名。該方法的核心思想是通過將學習內容簡化并用自己的話解釋給別人&#xff0c;來…

Node.js學習筆記-04

這第九章也是個大重點 九、玩轉進程 Node在選型時決定在V8引擎之上構建&#xff0c;也就意味著它的模型與瀏覽器類似。 本章關于進程的介紹和討論將會解決如下兩個問題&#xff1a; 單進程單線程并非完美&#xff0c;如今CPU基本均是多核的&#xff0c;真正的服務器&#xf…

背上小書包準備面試之TypeScript篇

目錄 typescript是啥&#xff1f;與javascript的區別&#xff1f; typescript數據類型&#xff1f; typescript中枚舉類型&#xff1f;應用場景&#xff1f; typescript中接口的理解&#xff1f;應用場景&#xff1f; typescript中泛型的理解&#xff1f;應用場景&#xf…

輕薄的ESL電子標簽有哪些特性?

在智慧物聯逐漸走進千萬家的當下&#xff0c;技術變革更加日新月異。ESL電子標簽作為科技物聯的重要組成部分&#xff0c;是推動千行百業數字化轉型的重要技術&#xff0c;促進物聯網產業的蓬勃發展。在智慧零售、智慧辦公、智慧倉儲等領域&#xff0c;ESL電子標簽在未來是不可…

win11右下角圖標(網絡,音量,電量)點擊無反應問題,兩分鐘解決!

win11系統用的好好的&#xff0c;突然有一天任務欄右下角的常用三件套&#xff08;網絡&#xff0c;音量&#xff0c;電量&#xff09;左鍵單擊沒反應&#xff0c;無法方便的調節音量和連接wifi&#xff0c;如下圖所示&#xff0c;但是右鍵好用&#xff0c;不過不方便。網上查了…

嵌入式 C 語言程序數據基本存儲結構

一、5大內存分區 內存分成5個區&#xff0c;它們分別是堆、棧、自由存儲區、全局/靜態存儲區和常量存儲區。 1、棧區(stack)&#xff1a;FIFO就是那些由編譯器在需要的時候分配&#xff0c;在不需要的時候自動清除的變量的存儲區。里面的變量通常是局部變量、函數參數等。 ?…