状态 API:useState 与 ref / reactive
聚焦 React useState 与 Vue ref、reactive 更新数字和对象状态时的 API 写法。
核心结论
React state 是一次 render 的快照,更新时应通过 setter 提交新值;Vue 的 ref 和 reactive 是稳定的响应式容器,可以修改 .value 或对象属性。
对象更新流程
Vue 3 × React
flowchart LR event["用户操作"] --> react["React: setState(prev => newValue)"] react --> snapshot["下一次 render 的新快照"] event --> vue["Vue: ref.value / reactive.key = value"] vue --> deps["触发读取该属性的依赖"]
图中实线表示主要数据或处理路径,虚线表示反馈、通知或下一轮更新。
完整 Demo 源码
以下代码直接读取在线 Demo 使用的源文件,没有省略或改写。
React 源码
import { useState } from "react";type Profile = { name: string; score: number;};export function ReactDemo() { const [count, setCount] = useState(0); const [profile, setProfile] = useState<Profile>({ name: "小明", score: 0, }); function increment() { setCount((current) => current + 1); setProfile((current) => ({ ...current, score: current.score + 1, })); } function reset() { setCount(0); setProfile((current) => ({ ...current, score: 0 })); } return ( <div className="demo-stack"> <div className="demo-card"> <span className="demo-tag">useState</span> <h2>{profile.name}的计数器</h2> <p>count:{count}</p> <p>score:{profile.score}</p> </div> <div className="demo-actions"> <button className="demo-button" type="button" onClick={increment}> 同时加一 </button> <button className="demo-button" type="button" onClick={reset}> 重置 </button> </div> </div> );}Vue 3 源码
<script setup lang="ts">import { reactive, ref } from "vue";const count = ref(0);const profile = reactive({ name: "小明", score: 0,});function increment() { count.value += 1; profile.score += 1;}function reset() { count.value = 0; profile.score = 0;}</script><template> <div class="demo-stack"> <div class="demo-card"> <span class="demo-tag">ref / reactive</span> <h2>{{ profile.name }}的计数器</h2> <p>count:{{ count }}</p> <p>score:{{ profile.score }}</p> </div> <div class="demo-actions"> <button class="demo-button" type="button" @click="increment"> 同时加一 </button> <button class="demo-button" type="button" @click="reset">重置</button> </div> </div></template>在线观察
两个计数器维护相同的数字与对象状态。重点观察 React 如何替换对象,Vue 如何修改响应式属性。
React
useState
小明的计数器
count:0
score:0
Vue 3
ref / reactive
小明的计数器
count:0
score:0
常见误区
- 不要直接修改 React state;旧对象引用可能让 React 无法可靠判断更新边界。
- 解构
reactive对象的基本类型属性会失去响应式连接,需要保留对象访问或使用toRefs。 - 新值依赖旧值时,React 优先使用函数式 setter,避免闭包中的旧快照。
- Vue 模板会自动解包 ref,但普通 TypeScript 代码仍需读取
.value。
原理见响应式系统与状态更新模型;需要从现有状态计算新值时继续阅读派生状态。