从 Valtio v1 迁移到 v2 的完整指南

从 Valtio v1 迁移到 v2 的完整指南

【免费下载链接】valtio 💊 Valtio makes proxy-state simple for React and Vanilla 【免费下载链接】valtio 项目地址: https://gitcode.com/gh_mirrors/va/valtio

前言:为什么要迁移到 v2?

还在为 React 状态管理而烦恼吗?Valtio v2 带来了革命性的改进!作为轻量级的代理状态管理库,Valtio v2 不仅完全拥抱 React 19 的新特性,还优化了性能表现和开发体验。本文将为你提供从 v1 到 v2 的完整迁移指南,让你在 30 分钟内完成平滑升级。

读完本文你将获得:

  • ✅ Valtio v2 的核心变化解析
  • ✅ Promise 处理的最佳实践方案
  • ✅ 对象复用的安全迁移策略
  • ✅ SSR 环境下的兼容性解决方案
  • ✅ 完整的代码示例和对比表格

Valtio v2 的核心变化概览

Valtio v2 主要围绕三个关键变化进行了重构:

mermaid

版本要求升级

  • React: ≥ 18.0.0(必需)
  • TypeScript: ≥ 4.5.0(必需)
  • 构建目标: ES2018

已移除的废弃功能

所有在 v1 中标记为废弃的 API 已被完全移除,确保代码库的整洁性。

核心迁移场景详解

1. Promise 处理的革命性变化

Valtio v2 最大的变化是放弃了内部的 Promise 处理机制,转而完全依赖 React 19 的 use hook。

v1 的 Promise 处理方式
// v1 - 自动处理 Promise
import { proxy, useSnapshot } from 'valtio'

const state = proxy({ 
  data: fetch('/api/data').then(res => res.json()) 
})

const Component = () => {
  const snap = useSnapshot(state)
  // v1 内部自动解析 Promise
  return <div>{JSON.stringify(snap.data)}</div>
}
v2 的正确迁移方式
// v2 - 显式使用 use hook
import { use } from 'react' // React 19 原生支持
import { proxy, useSnapshot } from 'valtio'

const state = proxy({ 
  data: fetch('/api/data').then(res => res.json()) 
})

const Component = () => {
  const snap = useSnapshot(state)
  // v2 需要显式使用 use hook
  return <div>{JSON.stringify(use(snap.data))}</div>
}
React 18 用户的兼容方案
// React 18 用户需要使用 shim
import { use } from 'react18-use' // 第三方兼容库
import { proxy, useSnapshot } from 'valtio'

const state = proxy({ 
  data: fetch('/api/data').then(res => res.json()) 
})

const Component = () => {
  const snap = useSnapshot(state)
  return <div>{JSON.stringify(use(snap.data))}</div>
}

2. proxy() 函数的行为变化

Valtio v2 中 proxy(obj) 从纯函数变为非纯函数,这会影响到对象复用的场景。

推荐用法(v1 和 v2 都兼容)
import { proxy } from 'valtio'

// ✅ 推荐:不重用传入的对象
const state = proxy({ count: 1, obj: { text: 'hi' } })

// ✅ 安全操作
state.obj = { text: 'hello' }
对象复用场景的迁移方案
// v1 - 对象复用模式
import { proxy } from 'valtio'

const initialObj = { count: 1, obj: { text: 'hi' } }
const state = proxy(initialObj)
// 后续继续使用 initialObj...

const newObj = { text: 'hello' }
state.obj = newObj
// 后续继续使用 newObj...
// v2 - 需要显式深拷贝
import { proxy } from 'valtio'
import { deepClone } from 'valtio/utils'

const initialObj = { count: 1, obj: { text: 'hi' } }
const state = proxy(deepClone(initialObj))
// 安全使用 initialObj...

const newObj = { text: 'hello' }
state.obj = deepClone(newObj)
// 安全使用 newObj...

3. useSnapshot() 的优化调整

v2 中对 useSnapshot() 进行了细微调整以确保与 useMemo 和未来 React 编译器的兼容性。虽然可能在极端情况下导致额外的重渲染,但对大多数应用来说影响微乎其微。

4. SSR 环境下的 useLayoutEffect 警告

在 React 18 SSR 环境中,需要添加条件逻辑来避免过多的警告:

import { snapshot, useSnapshot as useSnapshotOrig } from 'valtio'

// 检测是否为 SSR 环境
const isSSR = typeof window === 'undefined'

// 条件性 useSnapshot
export const useSnapshot = isSSR 
  ? (p) => snapshot(p)  // SSR 使用 snapshot
  : useSnapshotOrig     // 客户端使用原始 useSnapshot

// 在组件中正常使用
const Component = () => {
  const snap = useSnapshot(state)
  return <div>{snap.count}</div>
}

迁移检查清单

为了确保迁移过程顺利,请按照以下清单逐步检查:

检查项v1 状态v2 迁移方案完成状态
Promise 使用❌ 内部自动处理✅ 显式使用 use hook
对象复用❌ 可能产生副作用✅ 使用 deepClone
React 版本≥ 16.0.0≥ 18.0.0
TypeScript≥ 3.0.0≥ 4.5.0
SSR 兼容性❌ 可能有警告✅ 条件性 useSnapshot

常见问题解答

Q: 迁移到 v2 后性能会下降吗?

A: 不会。虽然 useSnapshot 有细微调整,但整体性能保持优秀,且更好的兼容性为未来优化奠定了基础。

Q: 如果我的项目还在用 React 17 怎么办?

A: 必须升级到 React 18 或更高版本。Valtio v2 强制要求 React ≥ 18.0.0。

Q: deepClone 的使用会影响性能吗?

A: 只在对象复用场景需要,正常使用模式下不会增加任何性能开销。

Q: 迁移过程中遇到问题如何调试?

A: 建议逐步迁移,先处理 Promise 相关代码,再检查对象复用场景,最后处理 SSR 兼容性。

总结

Valtio v2 的迁移虽然涉及一些 breaking changes,但整体迁移路径清晰明确。核心变化围绕:

  1. Promise 处理现代化 - 拥抱 React 19 use hook
  2. 对象操作安全化 - 显式深拷贝避免副作用
  3. 兼容性最优化 - 更好的 React 生态集成

遵循本文的指南,你可以在短时间内完成从 v1 到 v2 的平滑迁移,享受更现代化、更安全的开发体验。

💡 提示:迁移完成后,建议运行完整的测试套件,确保所有功能正常工作。

【免费下载链接】valtio 💊 Valtio makes proxy-state simple for React and Vanilla 【免费下载链接】valtio 项目地址: https://gitcode.com/gh_mirrors/va/valtio

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值