|
| 1 | +--- |
| 2 | +title: 'How to Migrate to v2 from v1' |
| 3 | +--- |
| 4 | + |
| 5 | +# How to Migrate to v2 from v1 |
| 6 | + |
| 7 | +## Changes in v2 |
| 8 | + |
| 9 | +React 19 officially introduces the `use` hook to handle promises. |
| 10 | +Valtio v1 internally handled promises, which is no longer recommended. |
| 11 | +In Valtio v2, promises are not handled internally, |
| 12 | +and developers should explicitly use the `use` hook to manage promises. |
| 13 | + |
| 14 | +Valtio v2 also introduces several changes in its design choices: |
| 15 | + |
| 16 | +First, the behavior of `proxy(obj)` has changed. In v1, it was a pure function and deeply copied `obj`. In v2, it is an impure function and deeply modifies `obj`. Generally, reusing `obj` is not recommended, and if you have followed this convention, nothing will break. |
| 17 | + |
| 18 | +Second, the behavior of `useSnapshot()` has been altered. Although it is a subtle change, it is less optimized to ensure compatibility with `useMemo` and the upcoming React compiler. The change may lead to extra re-renders in some edge cases, but it might not be noticeable. |
| 19 | + |
| 20 | +Other notable changes to keep things updated and fresh include: |
| 21 | + |
| 22 | +- Removal of all deprecated features |
| 23 | +- Requirement of React version 18 and above |
| 24 | +- Requirement of TypeScript version 4.5 and above |
| 25 | +- The build target updated to ES2018 |
| 26 | + |
| 27 | +## Migration for breaking changes |
| 28 | + |
| 29 | +### Resolving promises |
| 30 | + |
| 31 | +```js |
| 32 | +// v1 |
| 33 | +import { proxy, useSnapshot } from 'valtio' |
| 34 | + |
| 35 | +const state = proxy({ data: fetch(...).then((res) => res.json()) }) |
| 36 | + |
| 37 | +const Component = () => { |
| 38 | + const snap = useSnapshot(state) |
| 39 | + return <>{JSON.stringify(snap.data)}</> |
| 40 | +} |
| 41 | +``` |
| 42 | + |
| 43 | +```js |
| 44 | +// v2 |
| 45 | +import { use } from 'react' |
| 46 | +import { proxy, useSnapshot } from 'valtio' |
| 47 | + |
| 48 | +const state = proxy({ data: fetch(...).then((res) => res.json()) }) |
| 49 | + |
| 50 | +const Component = () => { |
| 51 | + const snap = useSnapshot(state) |
| 52 | + return <>{JSON.stringify(use(snap.data))}</> |
| 53 | + // If `data` is not an object, you can directly embed it in JSX. |
| 54 | + // return <>{snap.data}</> |
| 55 | +} |
| 56 | +``` |
| 57 | + |
| 58 | +### Impure `proxy(obj)` |
| 59 | + |
| 60 | +```js |
| 61 | +// v1 |
| 62 | +import { proxy } from 'valtio' |
| 63 | + |
| 64 | +const state = proxy({ count: 1, obj: { text: 'hi' } }) |
| 65 | +state.obj = { text: 'hello' } |
| 66 | +``` |
| 67 | + |
| 68 | +```js |
| 69 | +// v2 |
| 70 | +import { proxy } from 'valtio' |
| 71 | +import { deepClone } from 'valtio/utils' |
| 72 | + |
| 73 | +const state = proxy(deepClone({ count: 1, obj: { text: 'hi' } })) |
| 74 | +state.obj = deepClone({ text: 'hello' }) |
| 75 | +``` |
| 76 | + |
| 77 | +Note that `deepClone` is unnecessary unless you are reusing the object. |
| 78 | +It is generally recommended to avoid reusing the object. |
| 79 | + |
| 80 | +## Links |
| 81 | + |
| 82 | +- https://github.com/pmndrs/valtio/discussions/703 |
| 83 | +- https://github.com/pmndrs/valtio/pull/810 |
0 commit comments