VueJS

Understanding Side Effects in VueJS

Adesoji Temitope
2 min read
Understanding Side Effects in VueJS
This article was written over 18 months ago and may contain information that is out of date. Some content may still be relevant, but please refer to official documentation for the latest information.

Introduction

In this article, we will talk about side effects in VueJS, and how to prevent some of them. Side effects are not outrightly bad since they might have some usecase like in a setTimeout() function. But we need to try to ensure that we know about these side effects.

What are side effects?

A side effect is when a function changes or modifies data that does not exist in its local scope. A simple example is a function that receives a parameter which is an Array, and inside that function, it changes the data in that array.

Example:

const numberList = [ 1, 2, 3, 4, 5, 6 ];

function addItem( item ) {
  return item.push( ( item.length - 1 ) + 1 );
}

addItem( numberList )
console.log( numberList )

From this example above, we find out that numberList is been mutated when additem is called.

Side Effects in Vue

Example 1: Side Effects in Computed Properties

Lets try to create a side effect example in a computed property.

<template>
<div>
	Unsorted Data: {{ languages }}
</div>
<div>
	Sorted Data: {{ sortLanguages }}
</div>
</template>

<script>
export default {
  name: ‘languages-list’,
  data() {
    return {
       languages: [
           {
              name: "React",
           },
           {
              name: "Vue",
           },
           {
              name: "Angular",
           },
           {
              name: "Svelte",
           }
        ]
     },
  },
  computed: {
    sortLanguages() {
      return this.languages.sort( ( a, b ) => { 
        if ( a.name < b.name )  { return -1; }
        if ( a.name > b.name )  { return 1; }
        return 0;
      } )
    }
  }
}
</script>

From the example above, we would see that the Unsorted Data and Sorted Data are the same. this.languages data model gets mutated when sortedLanguages is referenced. This is a side effect that can result in unexpected behaviours in your application if not properly handled.

Example 2: Side effects wWen Accessing Getters

Lets try to create a side effect example when accessing and assigning a getters data model.

// store/index.js

state: {
	languages: [
        {
            name: "React",
        },
        {
            name: "Vue",
        },
        {
            name: "Angular",
        },
        {
            name: "Svelte",
        }
   ]
},
getters: {
	getLanguages: function ( state ) {
		return state.languages;
	}
},
actions: {
	sortLanguages: function ( context ) {
		const languages = JSON.parse( JSON.stringify( context.getters.getLanguages ) );
    return languages.sort( ( a, b ) => { 
        if ( a.name < b.name )  { return -1; }
        if ( a.name > b.name )  { return 1; }
        return 0;
      } )
  }
}

From this example, we would see that the store gets updated when we call (dispatch) the action sortLanguages. This is a side effect that can result in unexpected behaviours in your application, because the languages state is been mutated.

How Do We Resolve These Side Effects?

  • Shallow clone
  computed: {
    sortLanguages() {
      const languagesClone = this.languages.slice();
      return languagesClone.sort( ( a, b ) => { 
        if ( a.name < b.name )  { return -1; }
        if ( a.name > b.name )  { return 1; }
        return 0;
      } )
    }
  }

When we shallow clone a language's array using the .slice() method, it returns a shallow copy of a portion of the array into a new array object. We do this to prevent a mutation of the language's data model.

  • Deep clone
  computed: {
    sortLanguages() {
      const languagesClone = json.parse( json.stringify( this.languages ) );
      return languagesClone.sort( ( a, b ) => { 
        if ( a.name < b.name )  { return -1; }
        if ( a.name > b.name )  { return 1; }
        return 0;
      } )
    }
  }

To deep clone, we can simply use json.parse(json.stringify(()) on our data model.

JSON.stringify converts the data model to a string which removes references from the data model. JSON.parse converts the string back to an array of objects.

In Vue, side effects that modify reactive properties in the store can be hidden and cause unexpected bugs which can be difficult to trace and debug. It's my hope that this article helps you better identify and respond to side effects in VueJS.

If you have any questions or run into any trouble, feel free to reach out on Twitter or Github.

About the author

Adesoji Temitope

Adesoji Temitope

Software Engineer

Keep reading

View all posts →

Awesome 3D experience with VueJS and TresJS: a beginner's guide

Unleash the power of 3D in your Vue.js projects with Tres.js! The future of immersive web experiences is here. #Vuejs #3Ddevelopment...

Mattia Magi5 mins
Vue3D

3 VueJS Component Libraries Perfect for Beginners

For developers checking out VueJS for the first time, the initial steps are overwhelming, particularly when setting up projects from square one. But don’t worry! The VueJS ecosystem offers a plethora of remarkable component libraries, easing this early obstacle. These three libraries are pre built toolkits, providing beginners with the means to kickstart their VueJS projects effortlessly. Let’s take a look! Quasar Quasar is among the most popular open source component libraries for Vue.js, offering a comprehensive set of ready to use UI components and tools for building responsive web applications and websites. Designed with performance, flexibility, and ease of use in mind, Quasar provides developers with a wide range of customizable components, such as buttons, forms, dialogs, and layouts, along with built in support for themes, internationalization, and accessibility. With its extensive documentation, active community support, and seamless integration with Vue CLI and Vuex, Quasar empowers developers to rapidly prototype and develop high quality Vue.js applications for various platforms, including desktop, mobile, and PWA (Progressive Web Apps). PrimeVue PrimeVue is a popular Vue.js component library offering a wide range of customizable UI components designed for modern web applications. Developed by PrimeTek, it follows Material Design guidelines, ensuring responsiveness and accessibility across devices. With features like theming, internationalization, and advanced functionalities such as lazy loading and drag and drop, PrimeVue provides developers with the tools to create elegant and high performing Vue.js applications efficiently. Supported by clear documentation, demos, and an active community, PrimeVue is an excellent choice for developers seeking to streamline their development process and deliver polished user experiences. Vuetify Vuetify is a powerful Vue.js component library that empowers developers to create elegant and responsive user interfaces with ease. Built according to Google's Material Design guidelines, Vuetify offers a vast collection of customizable UI components, ranging from buttons and cards to navigation bars and data tables. Its comprehensive set of features includes themes, typography, layout grids, and advanced components like dialogues and sliders, enabling developers to quickly build modern web applications that look and feel polished. With extensive documentation, active community support, and ongoing development, Vuetify remains a top choice for Vue.js developers seeking to streamline their workflow and deliver visually stunning user experiences. For newcomers venturing into Vue.js, the initial setup might seem daunting. Thankfully, Vue.js offers a variety of component libraries to simplify this process. Quasar, PrimeVue, and Vuetify are standout options, each providing pre built tools to kickstart projects smoothly. Whether you prefer Quasar's extensive UI components, PrimeVue's Material Design inspired features, or Vuetify's responsive interfaces, these libraries cater to diverse preferences and project requirements. With their clear documentation and active communities, these libraries empower developers to start Vue.js projects confidently and efficiently, enabling Vue developers to create polished user experiences....

2 mins
VuetifyVueQuasar

Understanding Vue.js's <Suspense> and Async Components

In this blog post, we will delve into how <Suspense> and async components work, their benefits, and practical implementation strategies to make your Vue.js applications more efficient and user-friendly...

Jesús Padrón6 mins
VueWeb PerformanceUXJavaScript

Getting started with Vitepress

Create your static blog site using Vitepress. Setup and configure your site in minutes by following this step-by-step tutorial....

Simone Cuomo12 mins
VueViteVitepress