Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When using strict mode, you want to provide a deep copy of 'state' and 'getter' methods #1758

Closed
zzcong opened this issue May 20, 2020 · 4 comments

Comments

@zzcong
Copy link

zzcong commented May 20, 2020

What problem does this feature solve?

In strict mode, when you make a deep copy of an object inside 'state', the 'dep' in the object will be copied as well, and an error will be reported: 'do not mutate vuex store state outside mutation handlers.'

What does the proposed API look like?

function deepCopy (name) { return JSON.parse(JSON.stringify(state[name])) }

@kiaking
Copy link
Member

kiaking commented May 20, 2020

Sorry what is 'dep'? I've stored almost all kind of crazy data structure to state but never encountered the error. Could you provide the reproduction code for this?

@kiaking kiaking added the need repro Reproduction code is required label May 20, 2020
@cuebit
Copy link
Member

cuebit commented May 20, 2020

Since JSON.parse(JSON.stringify(...)) doesn't exhibit this behaviour, how are you performing the deep copy initially? Otherwise, seems like your state is originally malformed.

@kiaking Dep is the dependency object from Vue's observer.

@zzcong
Copy link
Author

zzcong commented May 21, 2020

这是一个 'codesandbox' 例子,请查看,Take a look at the console. While it doesn't affect the production environment, it does affect the developer's judgment in the development environment
image

image
image

@kiaking
Copy link
Member

kiaking commented May 21, 2020

You're not deep coping the object. So the warning is correct, you are mutating the original state inside component. slice method is shallow copy, you have to copy the object inside the array as well.

At first your store mutation is wrong. You need to change it to:

  mutations: {
    changeTest(state, list) {
      // state.test = list
      state.testList = list
    }
  }

Then, change your changeList method in your HelloWorld component:

changeList () {
  let list = this.testList.slice()

  list = list.map(v => {
    // Copy object.
    const newItem = { ...v }

    newItem.foo = 'barnew' 

    return newItem
  })

  this.changeTest(list)
}

However, if this is all you want to do, you can just map the list and be done with it.

changeList () {
  const list = this.testList.map((v) => {
    return { foo: 'barnew' }
  })

  this.changeTest(list)
}

Hope it gets you where you want to go 👍

@kiaking kiaking closed this as completed May 21, 2020
@kiaking kiaking removed the need repro Reproduction code is required label May 21, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants