自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

面試必問(wèn):React和Vue各自是如何更新視圖的?

開發(fā) 前端
React 組件的 ??state?? 是不可變的,每次更新狀態(tài)時(shí),我們并不會(huì)直接修改原來(lái)的 state,而是創(chuàng)建一個(gè)新的 state 對(duì)象,并用它替換舊的 state。

在 Vue 3 中,響應(yīng)式系統(tǒng)是基于 Proxy 代理實(shí)現(xiàn)的,而 React 的狀態(tài)管理和更新機(jī)制則完全不同。React 并沒有使用 Proxy,它主要依賴 狀態(tài)不可變性(Immutability) 和 調(diào)度(Reconciliation) 機(jī)制來(lái)觸發(fā)組件更新。

?? React 是如何實(shí)現(xiàn)狀態(tài)更新并觸發(fā) UI 變化的?

1??  State 是不可變的

React 組件的 state 是不可變的,每次更新狀態(tài)時(shí),我們并不會(huì)直接修改原來(lái)的 state,而是創(chuàng)建一個(gè)新的 state 對(duì)象,并用它替換舊的 state。例如:

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

const increment = () => {
  setCount(count + 1); // 生成新的 state,觸發(fā)更新
};

React 通過(guò) setState 或 useState 提供的 setCount 來(lái)觸發(fā)狀態(tài)更新。因?yàn)?nbsp;count + 1 返回的是一個(gè)新的值,所以 React 認(rèn)為狀態(tài)已變更。

2?? 觸發(fā) Re-render

當(dāng) state 發(fā)生變化時(shí),React 不會(huì)立即更新 UI,而是會(huì):

  1. 觸發(fā) 調(diào)度(Scheduling),將當(dāng)前組件標(biāo)記為需要更新;
  2. 合并多個(gè)狀態(tài)更新,在下一次渲染時(shí)一起應(yīng)用;
  3. 重新執(zhí)行組件函數(shù),得到新的 JSX 結(jié)構(gòu)。

示例:

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

  console.log("組件渲染了"); // 每次 state 更新時(shí),組件都會(huì)重新執(zhí)行

  return (
    <button onClick={() => setCount(count + 1)}>
      Count: {count}
    </button>
  );
}

每次 setCount 觸發(fā)時(shí),React 不會(huì)直接修改 DOM,而是會(huì)重新執(zhí)行 Counter 組件函數(shù),生成新的 JSX,然后 React 通過(guò) Diffing 算法 找出變化的地方,再進(jìn)行高效的 DOM 更新。

3?? Diffing 和 Reconciliation 機(jī)制

當(dāng) state 發(fā)生變化時(shí),React 并不會(huì)暴力重新渲染整個(gè)頁(yè)面,而是:

  • 比較(Diffing)新舊 Virtual DOM,找出變化的部分;
  • 高效更新(Reconciliation) 只修改受影響的 DOM 片段。

示例:

function App() {
  const [count, setCount] = useState(0);
  return (
    <div>
      <h1>Hello</h1>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

在 setCount(count + 1) 觸發(fā)后:

1.React 重新執(zhí)行 App 組件,生成新的 Virtual DOM

<div>
  <h1>Hello</h1>
  <p>Count: 1</p>  // 變化的地方
  <button>Increment</button>
</div>

2.React 發(fā)現(xiàn) h1 和 button 沒變,只更新 <p> 標(biāo)簽的文本內(nèi)容,而不是整個(gè) div。

4?? React 為什么不用 Proxy?

Vue 3 通過(guò) Proxy 直接監(jiān)聽對(duì)象的變化,實(shí)現(xiàn)細(xì)粒度的響應(yīng)式,而 React 依賴 不可變數(shù)據(jù) 和 Virtual DOM: ? React 方案的優(yōu)勢(shì):

  • 避免直接修改對(duì)象,防止副作用(確保狀態(tài)變更可預(yù)測(cè))。
  • 優(yōu)化性能:通過(guò) Diffing 機(jī)制減少不必要的 DOM 更新。
  • 適用于函數(shù)式編程,配合 useStateuseReducer 等 hook 進(jìn)行狀態(tài)管理。

缺點(diǎn):

  • 需要手動(dòng)使用 setState,不像 Vue 那樣直接修改對(duì)象就會(huì)自動(dòng)觸發(fā)更新。
  • 深層嵌套對(duì)象需要手動(dòng)更新:
const [user, setUser] = useState({ name: "Alice", age: 25 });

setUser({ ...user, age: 26 }); // 不能直接 user.age = 26
  • Vue 通過(guò) Proxy 代理可以自動(dòng)檢測(cè)到 user.age = 26 的變化,而 React 需要?jiǎng)?chuàng)建新對(duì)象才能觸發(fā)更新。

?? 總結(jié):React 如何更新 UI?

  1. 狀態(tài)不可變(Immutability):每次修改 state 時(shí),必須創(chuàng)建新的對(duì)象或值。
  2. 組件重新執(zhí)行:當(dāng) state 變化時(shí),React 重新運(yùn)行組件函數(shù),返回新的 JSX 結(jié)構(gòu)。
  3. Diffing & Reconciliation
  • React 比較新舊 Virtual DOM,找出變化的部分;
  • 只更新需要修改的 DOM 節(jié)點(diǎn),而不是整個(gè)頁(yè)面。

?? 這就是 React 不用 Proxy 也能高效更新 UI 的關(guān)鍵!

Vue 3 的更新過(guò)程主要依賴 響應(yīng)式系統(tǒng)(基于 Proxy 和 虛擬 DOM(Virtual DOM),它能夠高效地追蹤數(shù)據(jù)變化,并只更新需要修改的部分 DOM。下面詳細(xì)解析 Vue 3 的更新過(guò)程。

?? Vue 3 是如何觸發(fā) UI 更新的?

1?? 響應(yīng)式系統(tǒng)(Reactive System)

Vue 3 通過(guò) Proxy 代理對(duì)象的 get 和 set 操作,實(shí)現(xiàn)自動(dòng)追蹤依賴 & 觸發(fā)更新。當(dāng)你修改 state 時(shí),Vue 會(huì):

  • 追蹤數(shù)據(jù)(依賴收集)
  • 檢測(cè)變化(觸發(fā)更新)
  • 重新渲染 Virtual DOM 并更新真實(shí) DOM

?? 示例:Vue 3 如何監(jiān)聽數(shù)據(jù)變化

import { reactive } from "vue";

const state = reactive({ count: 0 });

console.log(state.count); // 訪問(wèn)屬性時(shí),Vue 記錄依賴
state.count++;  // 修改屬性時(shí),Vue 觸發(fā)更新

Vue 3 通過(guò) Proxy 代理 state,監(jiān)聽 count 變化,自動(dòng)通知視圖更新。

Vue 2 使用 Object.defineProperty() 只能監(jiān)聽對(duì)象已有的屬性,Vue 3 的 Proxy 解決了這個(gè)局限,支持監(jiān)聽新增/刪除的屬性。

2?? 依賴收集(Dependency Collection)

Vue 需要知道哪些組件或計(jì)算屬性依賴 state.count,這樣當(dāng) count 變化時(shí),它只會(huì)更新受影響的組件,而不是整個(gè)應(yīng)用。

工作流程:

  • 當(dāng)組件渲染時(shí),Vue 訪問(wèn) state.count,觸發(fā) get,將該組件注冊(cè)為 count 的依賴(收集副作用 effect)。
  • 以后 count 變化時(shí),Vue 會(huì)通知所有依賴它的地方更新。

示例:

import { reactive, effect } from "vue";

const state = reactive({ count: 0 });

// 創(chuàng)建一個(gè)副作用(Effect)
effect(() => {
  console.log("Count changed:", state.count);
});

state.count++; // 修改時(shí)觸發(fā) effect,打印 "Count changed: 1"

在 Vue 組件內(nèi)部,effect() 由 Vue 自動(dòng)管理,開發(fā)者無(wú)需手動(dòng)調(diào)用。

3?? 觸發(fā)更新(Trigger & Scheduler)

當(dāng) state.count++ 發(fā)生時(shí),Vue 觸發(fā) set 操作:

  1. Vue 先檢查 count 是否真的變化(新值 !== 舊值)。
  2. 如果變化了,Vue 通知 effect(視圖更新邏輯)重新執(zhí)行。
  3. Vue 使用 調(diào)度器(Scheduler) 合并多個(gè)狀態(tài)更新,避免不必要的重復(fù)渲染。

示例:多個(gè)狀態(tài)變化會(huì)合并更新

<script setup>
import { reactive } from "vue";

const state = reactive({ count: 0 });

function increment() {
  state.count++;  
  state.count++;  // Vue 不會(huì)觸發(fā)兩次 DOM 更新,而是合并優(yōu)化
}
</script>

<template>
  <p>{{ state.count }}</p>
  <button @click="increment">+2</button>
</template>

Vue 通過(guò) nextTick() 機(jī)制合并更新,減少 DOM 操作,提高性能。

4?? 重新渲染 Virtual DOM

當(dāng) state.count 變化后:

  1. Vue 重新執(zhí)行組件的渲染函數(shù),生成新的 Virtual DOM(虛擬 DOM) 結(jié)構(gòu)。
  2. Vue 對(duì)比新舊 Virtual DOM(Diffing 算法),找出變化的部分。
  3. Vue 只更新變更的 DOM 節(jié)點(diǎn),而不是整個(gè)頁(yè)面。

5?? Diffing & Patch 過(guò)程

Vue 3 使用 Patch Algorithm 進(jìn)行高效的 DOM 更新:

  • 如果 Virtual DOM 結(jié)構(gòu)沒變(只是內(nèi)容變了),Vue 直接更新文本內(nèi)容。
  • 如果子元素順序發(fā)生變化,Vue 采用最小修改策略,只移動(dòng)必要的節(jié)點(diǎn),而不是全部重繪。

示例:

<template>
  <ul>
    <li v-for="item in list" :key="item.id">{{ item.text }}</li>
  </ul>
</template>

<script setup>
import { reactive } from "vue";

const list = reactive([
  { id: 1, text: "Vue" },
  { id: 2, text: "React" }
]);

setTimeout(() => {
  list.reverse(); // Vue 只會(huì)調(diào)整 DOM 位置,而不會(huì)重新創(chuàng)建 <li>
}, 2000);
</script>

Vue 只移動(dòng) <li> 位置,而不會(huì)銷毀 & 重新創(chuàng)建整個(gè)列表。

?? Vue 3 的 UI 更新完整流程

1?? 訪問(wèn)響應(yīng)式數(shù)據(jù)(Proxy get) → 觸發(fā)依賴收集

2?? 數(shù)據(jù)變更(Proxy set) → 觸發(fā)更新(Effect 重新執(zhí)行)

3?? Vue 重新執(zhí)行渲染函數(shù),生成新的 Virtual DOM

4?? Vue 進(jìn)行 Diffing,找出變更的 DOM 節(jié)點(diǎn)

5?? Vue 使用 Patch 機(jī)制,僅更新需要修改的部分 DOM

相比 Vue 2,Vue 3 在依賴追蹤、調(diào)度和 Virtual DOM 更新上更高效!

?? Vue 3 和 React 更新機(jī)制對(duì)比

特性

Vue 3

React

響應(yīng)式原理

Proxy

 代理數(shù)據(jù),自動(dòng)追蹤依賴

useState

 / useReducer,數(shù)據(jù)不可變

依賴收集

訪問(wèn)數(shù)據(jù)時(shí)自動(dòng)收集(get

組件渲染時(shí)自動(dòng)關(guān)聯(lián) state

狀態(tài)變更

set

 操作觸發(fā)更新

setState()

 觸發(fā)更新

組件更新機(jī)制

重新運(yùn)行 渲染函數(shù) 生成 VDOM

重新執(zhí)行 組件函數(shù) 生成 VDOM

Diff 算法

只更新變化的部分

只更新變化的部分

批量更新

nextTick()

 自動(dòng)合并

React 事件中 setState 會(huì)合并

?? Vue 3 的 Proxy 監(jiān)聽數(shù)據(jù)變更,React 通過(guò) useState 返回新對(duì)象。Vue 自動(dòng)追蹤依賴,而 React 需要手動(dòng) setState。

?? 總結(jié):Vue 3 是如何更新界面的?

  1. Proxy 監(jiān)聽數(shù)據(jù)變化,訪問(wèn)數(shù)據(jù)時(shí)自動(dòng)收集依賴,修改數(shù)據(jù)時(shí)自動(dòng)觸發(fā)更新。
  2. 依賴收集(Effect 機(jī)制),組件只會(huì)在需要更新時(shí)重新渲染,而不會(huì)整個(gè)應(yīng)用重繪。
  3. 批量更新(Scheduler),合并多個(gè) setState 操作,減少不必要的渲染。
  4. Diffing & Patch 機(jī)制,Vue 只更新最小范圍的 DOM,而不是整個(gè)頁(yè)面。

?? Vue 3 更新機(jī)制的核心優(yōu)勢(shì)

更精準(zhǔn)的依賴追蹤:基于 Proxy,比 Vue 2 更高效,支持監(jiān)聽新增/刪除屬性? 更少的渲染開銷:只有真正變化的組件才會(huì)重新渲染? 更高效的 DOM 更新:使用 Diff 算法 & Patch 機(jī)制,只更新必要部分

Vue 3 結(jié)合了響應(yīng)式系統(tǒng) + Virtual DOM,讓 UI 更新更智能、更高效。希望這個(gè)解析對(duì)你理解 Vue 3 的更新機(jī)制有幫助!

責(zé)任編輯:武曉燕 來(lái)源: 大遷世界
相關(guān)推薦

2020-09-21 14:35:20

VuenextTick前端

2021-12-27 08:22:18

Kafka消費(fèi)模型

2023-02-17 08:02:45

@Autowired@Resource

2023-02-01 07:15:16

2021-12-09 12:22:28

MyBatis流程面試

2020-07-28 08:59:22

JavahreadLocal面試

2023-06-07 08:08:43

JVM內(nèi)存模型

2021-09-10 18:47:22

Redis淘汰策略

2023-02-15 07:03:41

跨域問(wèn)題面試安全

2021-12-06 11:03:57

JVM性能調(diào)優(yōu)

2023-02-03 07:24:49

雙親委派模型

2019-03-15 19:41:39

MySQL面試數(shù)據(jù)庫(kù)

2020-11-05 13:12:47

紅黑樹

2024-01-05 14:20:55

MySQL索引優(yōu)化器

2023-08-15 15:33:29

線程池線程數(shù)

2021-12-13 11:12:41

Spring事務(wù)失效

2023-02-06 07:01:51

2021-12-16 08:21:31

高并發(fā)消息中間件

2020-09-29 15:24:07

面試數(shù)據(jù)結(jié)構(gòu)Hashmap

2020-02-18 14:25:51

Java線程池拒絕策略
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)