javascript - JSON Object copy in Vuex getter - Stack Overflow

I'm finding some strange behavior with JSON in a Vuex getter: it seems it is contributing to a pas

I'm finding some strange behavior with JSON in a Vuex getter: it seems it is contributing to a pass-by-reference type of problem. For context - I'm developing a music app, which will have multiple "scenes", which each include collections of "tracks" (similiar to Ableton Live).

Here's my getter:

  newTrack: state => {
    let newTrack = JSON.parse(JSON.stringify(state.newTrackDefaults))
    return newTrack
  },

Here's the object it refers to:

  newTrackDefaults: {
    tune: [],
    // and other properties
  },

And then it is called by an action:

  setUpNewScene: context => {
    let newScene = JSON.parse(JSON.stringify(context.state.newSceneDefaults))
    let newTrack = context.getters.newTrack  
    console.log(newTrack) // this reveals that the problem is from the getter 
    newScene.tracks.push(newTrack)
    contextmit('addNewScene', newScene)
 }

So the problem with this code is, when I add items (pitch-references) to a track on the first scene, then added a new scene, the new scene automatically receives the same track as the first scene. This is reflected in the Vuex state (according to the DevTool), not just the rendering. Also, when the tracks on the first scene are updated by the user, the tracks on the new scene change accordingly. So instinctively, this feels like a pass-by-reference type of error.

Through various console.log experiments, I found that the getter was returning the "filled" track. It's fixable by skipping the getter and writing the action as:

  setUpNewScene: context => {
    let newScene = JSON.parse(JSON.stringify(context.state.newSceneDefaults))
    let newTrack =  JSON.parse(JSON.stringify(context.state.newTrackDefaults))
    console.log(newTrack) // this works fine
    newScene.tracks.push(newTrack)
    contextmit('addNewScene', newScene)
 }

... so though I have a fix, I'm puzzled as to the original behavior. Would the getter interfere with the JSON functions? Or what else might be going on to cause this?

I'm finding some strange behavior with JSON in a Vuex getter: it seems it is contributing to a pass-by-reference type of problem. For context - I'm developing a music app, which will have multiple "scenes", which each include collections of "tracks" (similiar to Ableton Live).

Here's my getter:

  newTrack: state => {
    let newTrack = JSON.parse(JSON.stringify(state.newTrackDefaults))
    return newTrack
  },

Here's the object it refers to:

  newTrackDefaults: {
    tune: [],
    // and other properties
  },

And then it is called by an action:

  setUpNewScene: context => {
    let newScene = JSON.parse(JSON.stringify(context.state.newSceneDefaults))
    let newTrack = context.getters.newTrack  
    console.log(newTrack) // this reveals that the problem is from the getter 
    newScene.tracks.push(newTrack)
    context.mit('addNewScene', newScene)
 }

So the problem with this code is, when I add items (pitch-references) to a track on the first scene, then added a new scene, the new scene automatically receives the same track as the first scene. This is reflected in the Vuex state (according to the DevTool), not just the rendering. Also, when the tracks on the first scene are updated by the user, the tracks on the new scene change accordingly. So instinctively, this feels like a pass-by-reference type of error.

Through various console.log experiments, I found that the getter was returning the "filled" track. It's fixable by skipping the getter and writing the action as:

  setUpNewScene: context => {
    let newScene = JSON.parse(JSON.stringify(context.state.newSceneDefaults))
    let newTrack =  JSON.parse(JSON.stringify(context.state.newTrackDefaults))
    console.log(newTrack) // this works fine
    newScene.tracks.push(newTrack)
    context.mit('addNewScene', newScene)
 }

... so though I have a fix, I'm puzzled as to the original behavior. Would the getter interfere with the JSON functions? Or what else might be going on to cause this?

Share Improve this question asked Apr 27, 2018 at 22:10 drenldrenl 1,3534 gold badges19 silver badges32 bronze badges 1
  • 1 check this javascript pass reference or value, then another improvement of your codes is using Object.assign replace JSON.parse(JSON.stringify(context.state)) – Sphinx Commented Apr 27, 2018 at 23:11
Add a ment  | 

1 Answer 1

Reset to default 6

Vuex getters are cached.

https://vuex.vuejs/en/getters.html

Like puted properties, a getter's result is cached based on its dependencies, and will only re-evaluate when some of its dependencies have changed.

If their dependencies don't change, getters return their last returned value. Presumably, you aren't mutating newTrackDefaults. This means that the getter newTrack will never update. Which means context.getters.newTrack is returning the same object every time. Therefore all the "new" tracks you think you're creating are actually the same track.

When dealing with default values, I like to create a function which returns the default values. Then I can call the function whenever and wherever I want, no funky caching business involved.

function newTrackDefaults() {
    return {
        tune:[],
        // and other properties
    }
}


setUpNewScene: context => {
    let newScene = JSON.parse(JSON.stringify(context.state.newSceneDefaults))
    let newTrack = newTrackDefaults() 
    newScene.tracks.push(newTrack)
    context.mit('addNewScene', newScene)
 }

Fun fact: Getters can return functions, so you can also fix it like this.

newTrack: state => () => {
    let newTrack = JSON.parse(JSON.stringify(state.newTrackDefaults))
    return newTrack
  },

Now you need to call the getter, because it's a function now.

let newTrack = context.getters.newTrack()

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744743170a4591149.html

相关推荐

  • javascript - JSON Object copy in Vuex getter - Stack Overflow

    I'm finding some strange behavior with JSON in a Vuex getter: it seems it is contributing to a pas

    8小时前
    50

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信