How can getters in vuex be utilized uniquely?

After dedicating two weeks to studying Vuex, I find myself pondering the true significance and purpose of getters in the framework.

I ran the following code snippet and everything seems to be functioning properly.

this.$store.getters["app/url"]

However, I realized that I can achieve the same result using the state as well.

this.$store.state.app.url

My confusion lies in the fact that getters require additional setup, such as seen below, adding unnecessary length to the code when we could simply retrieve the value using state alone.

const getters = {
    url: state => state.url 
};

Answer №1

In my opinion, there are three scenarios where getters can provide advantages over directly accessing the state:

  • Firstly, getters have the capability to return internal data in a more suitable format compared to how it is stored in the state. By performing this kind of transformation within your Vuex store, you can maintain the cleanliness of your components. For instance:
// Although setters are typically used here, this example illustrates...
const state = {
  values: {
    2014: 1000,
    2015: 2000,
    2016: 3000,
    2017: 4000,
    2018: 5000,
    2019: 6000,
    2020: 7000
  },
  startYear: 2016,
  endYear: 2019
}

const getters = {
  // Outputs something like [3000, 4000, 5000, 6000]
  currentValues (state) {
    const years = Object.keys(state.values);
    years.sort();

    return years
      .filter(year => year >= state.startYear && year <= state.endYear)
      .map(year => state.values[year]);
  }
}
  • Getters simplify the process of returning copies of data instead of the actual data, preventing accidental modifications to the store without using mutations. Utilizing methods like lodash deepClone or Object.assign for shallow objects allows you to create duplicates that can be altered independently in your component without affecting the store.
const state = {
  values: {
    2014: 1000,
    2015: 2000,
    2016: 3000,
    2017: 4000,
    2018: 5000,
    2019: 6000,
    2020: 7000
  },
}

// Within your component
const values = this.$store.state.values;
values[2021] = 8000;
// Unexpectedly modifying the store? Avoid that with a getter.
// Instead, utilize a getter

import { cloneDeep } from 'lodash-es';

const getters = {
  values (state) {
    return cloneDeep(state.values);
  }
}

// Adding 2021 in your component won't impact the state, preventing unintended side effects
  • Getters enable separation between the internal state of your Vuex store and the components that utilize it. It establishes a contract between the component and the store, allowing you to modify either component structure or store internals independently, facilitating code refactoring. While setting up initial getters may involve some boilerplate, you can streamline the process by creating a function that generates these getters automatically. If a getter requires complex logic beyond simply returning the state, you can customize it rather than tracking down all occurrences of direct state usage.
function generateGetters(keys) {
  return keys.reduce((acc, key) => {
    acc[key] = (state) => state[key];

    return acc;
  }, {});
}

const getters = {
  ...generateGetters(['values', 'url', 'someOtherKey'])
}

Answer №2

Getters are a helpful tool in Vuex for applying logic when retrieving data from the state. The Vuex documentation explains this concept well.

Think of getters as computed properties for stores.

For instance, imagine you have an array of items stored in your state:

items = [
    {
        name: "Keyboard",
        price: 100
    },
    {
        name: "Mouse",
        price: 50
    },
    {
        name: "Monitor",
        price: 500
    },
    {
        name: "PC",
        price: 1500
    },
    {
        name: "Headset",
        price: 80
    }
]

Now, if you want to retrieve a list of items that cost more than 250 from the state, you can use the following getter method:

getExpensiveItems(state) {
    return state.items.filter(i => i.price > 250);
}

To learn more about Vuex getters, check out the official documentation.

Sometimes we need to compute derived state based on the store's current state. For example, filtering through a list of items and counting them:

computed: {
 doneTodosCount () {
   return this.$store.state.todos.filter(todo => todo.done).length
 }
}

If multiple components require similar functionality, duplicating the function or using a shared helper is not ideal. This is where Vuex getters come into play. They act like computed properties and cache their results based on dependencies, re-evaluating only when necessary.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

javascript utilizing the canvas feature to resize and add graphics to an image

Is it possible to leverage Canvas for drawing over images that have been downloaded by users, all while adjusting the scale? For instance: User uploads an image Starts drawing on the image Zooms out and continues adding more drawings All modifications ...

`The error "mockResolvedValue is not recognized as a function when using partial mocks in Jest with Typescript

Currently, I am attempting to partially mock a module and customize the return value for the mocked method in specific tests. An error is being thrown by Jest: The error message states: "mockedEDSM.getSystemValue.mockResolvedValue is not a function TypeEr ...

Having trouble with your YouTube Live Stream not playing in the React Player version 2.9.0?

I successfully integrated react-player into my react.js website and it was working perfectly. However, after a few days, it suddenly stopped functioning. Even updating the plugin to version 2.9.0 did not resolve the issue. Strangely enough, standard YouTub ...

Struggling with updating state using splice method within an onClick event in React Hooks

CODE DEMO I'm facing an issue with my code snippet where it appears fine when I console.log it, but fails to set the state. The goal is to delete a box by using splice when clicked, however, something seems to be preventing it from working properly. ...

Troubleshooting: Else block not functioning as expected within a React JS map function

I have a notification feature that makes an API call every 10 seconds to display an alert based on the response. However, I'm encountering an issue where the div is not being rendered properly. The div should be displayed based on certain conditions w ...

Troubleshooting issues with the add-comment and remove-comment functionalities in a react-redux application

I'm working on a comment widget using react-redux. I've encountered an issue where, when I click on the add comment button, nothing happens. Also, when I try to delete a comment, I get an error saying that map is not a function even though I am p ...

Issue with AngularJS ui-router failing to resolve a service call

I am facing an issue while trying to implement the resolve feature in my ui-router state provider. Here is how I have configured it: app.config(['$stateProvider', '$urlRouterProvider', '$locationProvider', function ($stat ...

Issue with React.js: The formData is empty when trying to add a value from a file using material-ui-dropzone

I am currently working on integrating an upload feature using a library named material-ui-dropzone Although I believe the file upload process is functioning correctly, I encounter an issue with axios where the formData appears empty even prior to sending ...

How come ng-class doesn't apply to a specific class name?

I recently wrote the following code: <style> .dotted { border:dotted; } </style> .... <p ng-style="mystyle" ng-class="dotted">{{ answer }}</p> My intention was to have the paragraph element enclosed within a ...

Vue-Router: Altering the view of a parent component with a child route

In my parent view, I have a list and some metadata displayed in a right pane. I'm looking to replace the right pane component with specific item data when clicked on the list: export default { mode: 'history' base: process.env.BASE_URL, ...

Undefined output in Typescript recursion function

When working with the recursion function in TypeScript/JavaScript, I have encountered a tricky situation involving the 'this' context. Even though I attempted to use arrow functions to avoid context changes, I found that it still did not work as ...

Vue Js: Creating an array of checkboxes

I have a collection of checkboxes sourced from the main system object where I store all system settings (referred to as getSystem{}). Within this form, I am retrieving information about a User, who possesses an array of roles []. How can I cross-reference ...

Navigate the conversation within the dialog without affecting the content below

Is it possible to have a dialog with scrollable content on top of a page that is also scrollable, but when trying to scroll inside the dialog using the mouse wheel, only the dialog body scrolls and not the page below it? What approach can be used to accom ...

Transforming a function into an array in TypeScript

I attempted to use the map() function on a dataURL array obtained from the usePersonList() hook, but I am struggling to convert my function to an array in order to avoid errors when clicking a button. import Axios from "axios"; import React, { us ...

"Troubleshooting: Sending null values through Jquery ajax to an MVC controller

The issue: I am facing a challenge with saving events in a calendar through ajax by sending the content to my controller function. Despite my efforts, I constantly see null values being passed to my database. Upon inspecting the Network tools console log ...

How can we transfer functions between files in JavaScript when creating a service library?

There's a piece of code located in my identity service that I'm working with. export function sumbitLogin(username, password) { console.log(username, password); } I want to simplify the process of accessing services in my components without ...

Retrieve data from a JSON array using either JavaScript or PHP

Check out my code snippet: const newData = [{"new_id":"1","new_no":"1","total":"N.A"},{"new_id":"2","new_no":"3","total":"4"},{"new_id":"2","new_no":"4","total":"5"}]; Now, I need to extract specific details from this JSON data based on the 'new_no& ...

"Revolutionize Your Site with Endless Scrolling using q

I am currently in the process of developing a web application using create-react-app along with the packages Infinite-Scroller and qwest. (https://www.npmjs.com/package/react-infinite-scroller) (https://www.npmjs.com/package/qwest) This is how my code l ...

Integrating TypeScript into an established project utilizing React, Webpack, and Babel

Currently, I am in the process of integrating Typescript into my existing React, Webpack, and Babel project. I aim to include support for file extensions such as [.js, .ts, .tsx] as part of my gradual transition to Typescript. I have made some progress, b ...

Having trouble accessing variable values within the nth-child selector in JavaScript

I am attempting to utilize the value of a variable within the element selector p:nth-child(0). Instead of hardcoding the number as 0, I want to dynamically assign the value of a variable. In this case, the variable is represented by i in a for loop. Howev ...