Vuejs Mutating Object passed as a prop
Asked Answered
S

2

6

If I'm passing (a reference to) an Object as a prop is it OK to mutate values in the prop?

I'm developing a web app which will require a lot of values to be passed to a component, and I'm trying to find the best way of passing the values to the component and back to the parent.

From everything I've read mutating a prop is the wrong way to do things, because next time the component is updated the values are passed back to the child component overwriting the mutations. But only the reference to the object is passed so any mutations to the values in the object prop happen to the original object in the parent component. Also Vuejs does not complain about mutating props when this happens.

const subComponent = {
    name: "subComponent",
  template: `
    <div>
        Sub Component Input
        <input type="text" v-model="objectProp.val1"></input>
    </div>`,
  props: {
    objectProp: {
      required: false,
      default: () => {return {val1: "carrot"}}
    }
  }
}

const aComponent = {
    name: "aComponent",
  template: `
    <div>
        val1: {{mainObject.val1}}
        val2: {{mainObject.val2}}
        <sub-component :objectProp="mainObject"></sub-component>
    </div>`,
  data: function() {
      return{
        mainObject: {
        val1: "foo",
        val2: "bar"
      }
    }
  },
  components: {
    subComponent
  }
}

new Vue({
  el: "#app",
    components: {
    aComponent
  }
})

Here is a JSFiddle showing an object prop being mutated.

JSFiddle

Scherzo answered 17/9, 2019 at 21:1 Comment(3)
if it works, then it's fine, by definition. from what you describe, the mutation won't hurt anything. if you're using an immutable state strategy with something like flux, then you should follow that system's best practices, but there is no general javascript-wide rule about mutating certain states from one place. This is kind of off-topic as an opinion question.Speleology
It does not complain because the dev check does not test for deep changes, but the mutation is just as bad.Serial
It sounds silly how everybody yelling "props mutation is bad, even on objects", but no one knows why, all the arguments they made is about primitive values only, it would be great if someone gives a real case of why mutation object props is bad, otherwise, I'll jump out of the box and say it is ok.Primrose
S
8

Is mutating a prop bad practice?

Yes absolutely. In more complex applications it is very easy to lose track of where/what/why is mutated

What is the right way to handle state across different components?

In small projects you can really do whatever you want, because you will most likely be able to follow the logic - even after not looking at the project for a year. The possibilities include:

  1. Mutating Props (ugly but will work)
  2. Using Events to mutate state in parent components; take a look at the EventBus (better)
  3. Use global shared state; look at Vuex (best, but a little more boilerplate)

In big projects, however, you should absolutely use Vuex. It is a module for Vue that adds global shared state to your app, which you can access and mutate from all places in your app.

Sena answered 17/9, 2019 at 21:11 Comment(0)
M
0

I think I understand what you are trying to do, You want to pass data to a child component, mutate it and then give that data back to the parent component.

You never want to mutate the props data given to the child component, however you CAN mutate a local state of the data, which could be an exact clone of the prop.

You can do this in many ways, I normally use a computed property as suggested in the Vue documentation: https://v2.vuejs.org/v2/guide/components-props.html

in the computed return, just return the data coming in from the property.

Mac answered 18/9, 2019 at 15:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.