Skip to content

Commit

Permalink
fix(patch): avoid merging reactive objects
Browse files Browse the repository at this point in the history
Fix #528
  • Loading branch information
posva committed Jun 7, 2021
1 parent 208e6c0 commit 581bd08
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 2 deletions.
54 changes: 53 additions & 1 deletion __tests__/store.patch.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { defineStore, setActivePinia, createPinia, Pinia } from '../src'
import { reactive, ref } from '@vue/composition-api'
import { createPinia, defineStore, setActivePinia, Pinia } from '../src'

describe('store.patch', () => {
let pinia: Pinia
Expand Down Expand Up @@ -84,4 +85,55 @@ describe('store.patch', () => {
list: [],
})
})

describe('skipping nested objects', () => {
const useStore = () => {
// create a new store
setActivePinia(createPinia())
return defineStore({
id: 'main',
state: () => ({
arr: [] as any[],
item: { a: 0, b: 0 } as null | { a: number; b?: number },
}),
})()
}

it('ref', () => {
const store = useStore()
const item = ref({ a: 1, b: 1 })
const oldItem = store.item
// @ts-expect-error: because it's a ref
store.$patch({ item })
expect(oldItem).toEqual({ a: 0, b: 0 })
expect(store.item).toEqual({ a: 1, b: 1 })
})

it('nested ref', () => {
const store = useStore()
const item = ref({ nested: { a: 1, b: 1 } })
const oldItem = store.item
store.$patch({ item: item.value.nested })
expect(oldItem).toEqual({ a: 0, b: 0 })
expect(store.item).toEqual({ a: 1, b: 1 })
})

it('reactive', () => {
const store = useStore()
const item = reactive({ a: 1, b: 1 })
const oldItem = store.item
store.$patch({ item })
expect(oldItem).toEqual({ a: 0, b: 0 })
expect(store.item).toEqual({ a: 1, b: 1 })
})

it('from store', () => {
const store = useStore()
store.arr.push({ a: 1, b: 1 })
const oldItem = store.item
store.$patch({ item: store.arr[0] })
expect(oldItem).toEqual({ a: 0, b: 0 })
expect(store.item).toEqual({ a: 1, b: 1 })
})
})
})
9 changes: 8 additions & 1 deletion src/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import {
provide,
UnwrapRef,
set,
isRef,
isReactive,
} from '@vue/composition-api'
import {
StateTree,
Expand Down Expand Up @@ -50,7 +52,12 @@ function innerPatch<T extends StateTree>(
for (const key in patchToApply) {
const subPatch = patchToApply[key]
const targetValue = target[key]
if (isPlainObject(targetValue) && isPlainObject(subPatch)) {
if (
isPlainObject(targetValue) &&
isPlainObject(subPatch) &&
!isRef(subPatch) &&
!isReactive(subPatch)
) {
target[key] = innerPatch(targetValue, subPatch)
} else {
// @ts-expect-error
Expand Down

0 comments on commit 581bd08

Please sign in to comment.