AlekseyHoffman
AlekseyHoffman

Reputation: 2694

Vuex - why don't JS variables work as expected?

Problem

JS variables don't work as expected in Vuex store.

Let's say we want to clear an array called content:

state: {
  content: [1, 2, 3]
}

We could do it either directly:

state.content = []

Or if it's referenced multiple times, we would put it in a variable first and then modify it, like this:

let content = state.content
content = []

But for some reason, the second method doesn't work. Why?

Code

Demo: https://jsfiddle.net/dke68gwz/

state: {
  content: [1, 2, 3]
},
mutations: {
  clearContent(state) {
    // Method 1 - works
    state.content = []

    // Method 2 - doesn't work
    // let content = state.content
    // content = []
  }
}

Upvotes: 1

Views: 63

Answers (4)

That's because the content variable is a new instance, and you use the a computed variable using the state.content. That is, the state.content remains the same but now you have a new variable content, empty.

if you want use this any way, you can use:

let content = state.content;
content = [];
state.content = content;

Upvotes: 1

Leviathan_the_Great
Leviathan_the_Great

Reputation: 448

I would say it is because you are are making a copy of only the property of the state obj. essentially you are copying only a property from the object that actually has the "change" event listener attached. In essence, you are orphaning the property from the object that would be tracking it's changes.

let me know if this helps!

Upvotes: 1

Jorg
Jorg

Reputation: 7250

It's not so much to do with Vue as it is the nature of JavaScript. Anything except primitives in JavaScript are pass-by-reference right, so let content = state.content creates a reference.

When you're doing the assignment content = [] you're essentially killing the reference that content had to state.content and you're giving it a new value.

const state = { content: [1, 2, 3] }
let content = state.content


// [1, 2, 3], [1, 2, 3]
console.log(state.content, content)

// [1, 2, 3, 4], [1, 2, 3, 4]
// still using the existing reference
content.push(4)
console.log(state.content, content)

// [1, 2, 3, 4], []
// reference is gone, new assignment
content = []
console.log(state.content, content)

Upvotes: 1

StackSlave
StackSlave

Reputation: 10627

You are just assigning [] to the content variable in the second example. This does not effect state.content. If you did content.splice(0) that would, however, empty the state.content Array. Assignment is just that, assignment. The variable assigned a non-primitive value is the same as the non-primitive. This does not mean that overwriting the variable eliminates the non-primitive. It just reassigns the variable.

const state = {
  content: [1, 2, 3]
}
const content = state.content;
content.splice(0);
console.log(content);

Upvotes: 1

Related Questions