selective-object-reuse
v1.0.6
Published
Simple javascript object wrapper that recursively substitutes object-like properties if they match the previously stored values
Downloads
632
Maintainers
Readme
Selective Object Reuse
Simple javascript object wrapper that recursively substitutes object-like properties if they match the previously stored values.
https://www.npmjs.com/package/selective-object-reuse
npm i --save selective-object-reuse
Simple Example
const a = { v: 1, obj: { test: 1 } }
const b = { v: 2, obj: { test: 1 } }
console.log(a === b) // False
console.log(a.obj === b.obj) // False
but
import { SelectiveObjectReuse } from 'selective-object-reuse'
const sor = new SelectiveObjectReuse()
const a = sor.wrap({ v: 1, obj: { test: 1 } })
const b = sor.wrap({ v: 2, obj: { test: 1 } })
console.log(a === b) // False
console.log(a.obj === b.obj) // True
Vue/Vuex Example
Let's consider some vue/vuex app that has to draw a list of users with tags (many-to-many relation). That's how the state may look like:
export const state = () => ({
userIds: [1, 2, 3]
users: {
1: { id: 1, name: 'First' },
2: { id: 2, name: 'Second' },
3: { id: 3, name: 'Third' }
},
tags: {
1: { id: 1, name: 'Red' },
2: { id: 2, name: 'Blue' }
},
userTags: [
{ userId: 1, tagId: 1 },
{ userId: 1, tagId: 2 },
{ userId: 2, tagId: 1 }
]
})
export const getters = {
usersWithTags: (state) => state.userIds.map(userId => ({
id: userId,
user: state.users[userId],
tags: userTags
.filter(userTag => userTag.userId === userId)
.map(userTag => state.tags[userTag.tagId])
}))
}
Every time when the state changes, the getter builds a new array consisting on new objects having tags
property that is a new array.
<template>
<UserWithTags
v-for="userWithTags in $store.getters.usersWithTags"
:key="userWithTags.id"
:user="userWithTags.user"
:tags="userWithTags.tags"
/>
</template>
Every time when one new user<->tag relation is created, every <UserWithTags>
component is updated because it refers to the new tags
array. It happens even for users without tags.
Selective Object Reuse solves this issue. It wraps any object, and when the last is recreated it recursively replaces unchanged parts back with currently stored objects.
<template>
<UserWithTags
v-for="userWithTags in $store.getters.usersWithTags"
:key="userWithTags.id"
:user="userWithTags.user"
:tags="sor.wrap(userWithTags.tags)"
/>
</template>
<script>
import { SelectiveObjectReuse } from 'selective-object-reuse'
export default {
data() {
return {
sor: new SelectiveObjectReuse()
}
}
}
</script>