orest's avatar
Level 13

vue unexpected reactivity

I just noticed an unexpected behaviour and now I don't know if it is normal or not.

I have a component named follows and a child component named follow-list-modal

I'm passing a followList (pagination ) from follows to its child component follow-list-modal

In the follow-list-modal I store the paginated array in the variable members

Follows.vue
<template>
   <div>
         <follow-list-modal
           :follow-list="dataset">
          </follow-list-modal>
  
   </div>
</template>
<script>
export default {
props: {
   dataset: {
      type: Object,
      default: {},
    },
  },
}
</script>
FollowListModal.vue
<template>
   <div>
      <button @click="fetchMore"> More </button>
   </div>
</template>
<script>
export default {
props: {
   followList: {
      type: Object,
      default: {},
    },
data() {
    return {
      members: this.followList.data,
      dataset: this.followList,
    };
  },
methods: {
    fetchMore() {
            let nextPage = parseInt(this.dataset.current_page)  + 1;
            axios
              .get(this.dataset.path + '?page=' + nextPage)
              .then(({ data }) => this.refresh(data))
              .catch((error) => console.log(error));
           }
},
refresh(paginatedCollection) {
      this.dataset = paginatedCollection;
      this.members = this.members.concat(...paginatedCollection.data);
    },
}

When I click the button More in the follow-list-modal to get more data, I then want to append the new data to the members array.

The unexpected behaviour ( for me at least ). is that if I use push in the refresh method

this.members.push(..paginatedCollection.data); 

It appends data not only to members but also to followList which is data that comes from the parent component follows

But if I use concat instead of push, it appends data only to members variable and not to followList

this.members = this.members.concat(..paginatedCollection.data);

Is this behaviour normal ?

I don't get why the followList changes when the members variable changes, I thought that reactivity is one way.

In other words, the members changes when the followList changes, but not the other way around

P.S I don't emit any events from follow-list-modal to follows or change the data of the follows component in any way from the follow-list-modal

0 likes
1 reply
dcranmer's avatar
dcranmer
Best Answer
Level 6

This might be part of your problem. From the Vue docs:

Note that objects and arrays in JavaScript are passed by reference, so if the prop is an array or object, mutating the object or array itself inside the child component will affect parent state.

So in this case it might be better to initialize your data properties using a copy of the followList object; e.g., something like

members: { ... this.followList.data}

Please or to participate in this conversation.