跳转到内容

React render 与 Vue setup

两个 Demo 都维护计数和显示模式,并记录组件逻辑的执行次数。操作结果相同,但状态更新后重新工作的范围不同。

React

每次 state 更新都会重新执行函数组件。

在线预览

函数组件执行

标准视图

count:0

ReactDemo 本次挂载已执行:1

组件关系与数据流

StateComponentRender / SetupHandler

差异焦点组件函数是 render 过程,不是只运行一次的初始化函数。

实线表示依赖、数据或命令传递,虚线表示事件、回调或清理路径。

flowchart TB
  accTitle: React 函数组件重新执行模型
  accDescr: 事件调用 setter 后更新 state,React 调度一次新的 render,重新执行 ReactDemo 函数并生成下一棵 UI。
  event{{"点击事件"}} --> setter{{"调用 state setter"}}
  setter --> state(["count / compact state"])
  state --> schedule{{"调度新的 render"}}
  schedule --> demo["重新执行 ReactDemo"]
  demo -.->|"创建下一次事件处理函数"| event
  class state state
  class demo component
  class event,setter,schedule process
  classDef state fill:#ffffff,stroke:#149eca,color:#172033,stroke-width:1.2px
  classDef component fill:#e5f6fb,stroke:#149eca,color:#172033,stroke-width:2px,font-weight:600
  classDef process fill:#f4fbfd,stroke:#149eca,color:#172033,stroke-width:1.6px
  classDef resource fill:#f3f5f8,stroke:#778195,color:#172033,stroke-width:1.4px

任意本地 state 更新都会调度 render,ReactDemo 函数从头再次执行。

React 流程图
React 组件关系与数据流

滚轮缩放 · 按住拖动 · 双击重置 · Esc 关闭

实际运行源码

import { useRef, useState } from "react";
export function ReactDemo() {
const executions = useRef(0);
const [count, setCount] = useState(0);
const [compact, setCompact] = useState(false);
executions.current += 1;
return (
<div className="demo-stack">
<div className="demo-card">
<span className="demo-tag">函数组件执行</span>
<h2>{compact ? "紧凑视图" : "标准视图"}</h2>
<p>count:{count}</p>
<p>ReactDemo 本次挂载已执行:{executions.current} 次</p>
</div>
<div className="demo-actions">
<button
className="demo-button"
type="button"
onClick={() => setCount((current) => current + 1)}
>
count + 1
</button>
<button
className="demo-button"
type="button"
onClick={() => setCompact((current) => !current)}
>
切换显示模式
</button>
</div>
</div>
);
}
Vue 3

setup 创建一次逻辑,响应式依赖负责后续更新。

在线预览

setup 执行

标准视图

count:0

VueDemo 本次挂载已执行 setup:1 次

组件关系与数据流

StateComponentRender / SetupHandler

差异焦点状态变化不会让 setup 从头执行,已有闭包和响应式引用继续复用。

实线表示依赖、数据或命令传递,虚线表示事件、回调或清理路径。

flowchart TB
  accTitle: Vue setup 与响应式更新模型
  accDescr: setup 创建 refs 和事件函数一次,点击后直接修改 ref,响应式系统只调度读取该值的模板更新。
  setup{{"setup 创建一次"}} --> state(["count / compact refs"])
  setup --> handlers[("稳定的事件函数")]
  handlers -.->|"直接修改 ref"| state
  state --> trigger{{"触发响应式依赖"}}
  trigger --> template["更新相关模板节点"]
  class state state
  class template component
  class setup,trigger process
  class handlers resource
  classDef state fill:#ffffff,stroke:#42b883,color:#172033,stroke-width:1.2px
  classDef component fill:#e7f8f0,stroke:#42b883,color:#172033,stroke-width:2px,font-weight:600
  classDef process fill:#f2fbf7,stroke:#42b883,color:#172033,stroke-width:1.6px
  classDef resource fill:#f3f5f8,stroke:#778195,color:#172033,stroke-width:1.4px

setup 保留 refs 和事件函数,状态变化后按响应式依赖更新模板。

Vue 3 流程图
Vue 3 组件关系与数据流

滚轮缩放 · 按住拖动 · 双击重置 · Esc 关闭

实际运行源码

<script setup lang="ts">
import { ref } from "vue";
const setupExecutions = 1;
const count = ref(0);
const compact = ref(false);
</script>
<template>
<div class="demo-stack">
<div class="demo-card">
<span class="demo-tag">setup 执行</span>
<h2>{{ compact ? "紧凑视图" : "标准视图" }}</h2>
<p>count:{{ count }}</p>
<p>VueDemo 本次挂载已执行 setup:{{ setupExecutions }} 次</p>
</div>
<div class="demo-actions">
<button class="demo-button" type="button" @click="count += 1">
count + 1
</button>
<button class="demo-button" type="button" @click="compact = !compact">
切换显示模式
</button>
</div>
</div>
</template>