- Vue3: "Dependency-driven" centered on effect
- React: "Re-execution driver" centered on render + Hooks
1. Comparison in one sentence (establish your mind first)
| Dimensions | Vue3 | React |
|---|---|---|
| Core units | effect(fn) | render(Component) |
| Update model | Exact dependency trigger | Rerun the entire function |
| Responsive granularity | Attribute level | Component level |
| Side Effect Scheduling | scheduler | Scheduler + Fiber |
| Data flow | pull (who uses it, who collects it) | push (setState push) |
2. Vue3 effect
1️⃣The essence of effect
ts
effect(() => {
console.log(state.count)
})What happened:
effect(fn)Push (activeEffect)state.count→ gettertrack(target, key)- Create a mapping of key → effect
txt
state.count
↓
Set(effect)2️⃣ Trigger update
ts
state.count++- setter
trigger(target, 'count')- Find dependency effects accurately
- execute or scheduler(effect)
👉 Will not affect effects that do not use count
3️⃣The core advantages of Vue effect
- Depends on automatic collection
- Extremely fine particle size
- effect ≠ render
- computed / watch are essentially effects
3. React Hooks: A completely different idea
1️⃣The core of React is not Hook, but render
jsx
function App() {
const [count, setCount] = useState(0)
return <div>{count}</div>
}⚠️ Key points:
Component function itself = render effect
2️⃣ What happened to setState
ts
setCount(1)- Create update
- Enter Fiber updateQueue
- Scheduler
- Re-execute the entire component function
txt
render(App)
├─ useState
├─ useEffect
├─ JSX👉 React I don’t know if you use count 👉 It chooses: I will run it all
3️⃣The essence of Hooks
Hooks ≠ Responsive
ts
useState
useEffect
useMemoThe essence is:
ts
hook[i]- Depends on calling order
- Rely on Fiber.memoizedState
- Each render order must be consistent
4. Dependency comparison: automatic vs manual (the most essential difference)
Vue computed
ts
computed(() => a.value + b.value)- Automatic track in getter
- a / b change → trigger
React useMemo
ts
useMemo(() => a + b, [a, b])- Your handwriting depends on
- Less writing = bug
- Writing too much = performance issues
🧠 React gives you control
5. effect vs useEffect (similar names, completely different semantics)
Vue effect | React useEffect | |
|---|---|---|
| Positioning | Responsive Core | Side Effects Hook |
| Whether to render | ❌ | ❌ |
| Whether to rely on collection | ✅ Automatic | ❌ Manual |
| Scheduling timing | Synchronization/microtask | After commit |
| Whether it can be nested | ✅ | ❌ |
⚠️ Don’t use useEffect as watch
6. Comparison of scheduling models (scheduler)
Vue
txt
setter → trigger → scheduler → jobQueue- effect has scheduler
- computed is lazy
- watch can flush sync / post
React
txt
setState
→ Scheduler(lane)
→ render(可中断)
→ commit(不可中断)- render can be interrupted
- commit must be completed
- Concurrency from Fiber
7. Why is React capable of concurrency but Vue doesn’t emphasize it?
Vue problem
- The effect granularity is too fine
- Dependencies are complex
- High disruption costs
Choice of React
- Coarse-grained render
- render can be rerun
- Native support for interrupt/retry
👉 This is the design premise of Fiber
8. Closure problem: Almost none in Vue, but everywhere in React
React closure trap
ts
useEffect(() => {
setInterval(() => {
console.log(count)
}, 1000)
}, [])👉 count is always the initial value
Vue won’t
ts
watchEffect(() => {
console.log(count.value)
})9. One-to-one correspondence at the source code level (core comparison)
| Vue3 | React |
|---|---|
effect | renderWithHooks |
track | handwritten deps |
trigger | dispatchAction |
| scheduler | Scheduler |
| Dep Map | Fiber.memoizedState |
10. Summary
- Vue3 is "reactive engine + compiler"
- React is "re-runnable pure functions + scheduling system"
It’s not who is more advanced, but the choices are different.