Skip to content

Commit

Permalink
fix(shallowReactive): don't trigger watchers for oldVal === newVal (#894
Browse files Browse the repository at this point in the history
)

Co-authored-by: Anthony Fu <anthonyfu117@hotmail.com>
  • Loading branch information
chearon and antfu committed Jan 27, 2022
1 parent 7243ffa commit 2a88e71
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 1 deletion.
9 changes: 9 additions & 0 deletions src/reactivity/force.ts
@@ -0,0 +1,9 @@
let _isForceTrigger = false

export function isForceTrigger() {
return _isForceTrigger
}

export function setForceTrigger(v: boolean) {
_isForceTrigger = v
}
3 changes: 3 additions & 0 deletions src/reactivity/reactive.ts
Expand Up @@ -14,6 +14,7 @@ import { isComponentInstance, defineComponentInstance } from '../utils/helper'
import { RefKey } from '../utils/symbols'
import { isRef, UnwrapRef } from './ref'
import { rawSet, accessModifiedSet } from '../utils/sets'
import { isForceTrigger } from './force'

export function isRaw(obj: any): boolean {
return Boolean(
Expand Down Expand Up @@ -213,6 +214,8 @@ export function shallowReactive(obj: any) {
},
set: function setterHandler(newVal: any) {
if (getter && !setter) return
const value = getter ? getter.call(obj) : val
if (!isForceTrigger() && value === newVal) return
if (setter) {
setter.call(obj, newVal)
} else {
Expand Down
3 changes: 3 additions & 0 deletions src/reactivity/ref.ts
Expand Up @@ -3,6 +3,7 @@ import { proxy, isPlainObject, warn, def } from '../utils'
import { reactive, isReactive, shallowReactive } from './reactive'
import { readonlySet } from '../utils/sets'
import { set } from './set'
import { setForceTrigger } from './force'

declare const _refBrand: unique symbol
export interface Ref<T = any> {
Expand Down Expand Up @@ -184,7 +185,9 @@ export function shallowRef(raw?: unknown) {
export function triggerRef(value: any) {
if (!isRef(value)) return

setForceTrigger(true)
value.value = value.value
setForceTrigger(false)
}

export function proxyRefs<T extends object>(
Expand Down
20 changes: 19 additions & 1 deletion test/v3/reactivity/ref.spec.ts
Expand Up @@ -250,11 +250,29 @@ describe('reactivity/ref', () => {
expect(dummy).toBe(1) // should not trigger yet

// force trigger
// sref.value = sref.value;
triggerRef(sref)
expect(dummy).toBe(2)
})

test('shallowRef noop when assignment is the same', () => {
const sref = shallowRef(1)
let calls = 0
watchEffect(
() => {
sref.value
calls++
},
{ flush: 'sync' }
)
expect(calls).toBe(1)

sref.value = 2
expect(calls).toBe(2)

sref.value = 2
expect(calls).toBe(2)
})

test('isRef', () => {
expect(isRef(ref(1))).toBe(true)
expect(isRef(computed(() => 1))).toBe(true)
Expand Down

0 comments on commit 2a88e71

Please sign in to comment.