Search code examples
javascriptfluxvuex

Structuring the state in a Vuex Store


I recently started learning Vuex and I would like to have some insight on how to properly structure the state of a Vuex/Flux-like stores

Lets take a look at the example below

ProductStore

state: {
  name: 'some name',
  price: 'some price',
  variants: [],
  selectedVariant: {},
}

mutations: {
  [ADD_VARIANT] (state, newVariant) {
    state.variants.push(newVariant)
  }

  [DELETE_VARIANT] (state, deletedId) {
    state.variants = _.filter(state.variants, c => c.id == deleteID )
  }

  [EDIT_VARIANT] (state, editedComment) {
    //...
  }

  [EDIT_SELECTED_VARIANT_TYPE] (state, variantType) {
    state.selectedVariant.type = variantType
  }
}

How do you structure states in instances like the one above when you have a parentComponent of sorts(the Product) and you have to manage childComponent states as well(the Variant).

In my specific instance, I have a ProductPage. In it, I have a VariantTable. Selecting an item in the VariantTable brings up a VariantModal that lets you edit variant attributes which should propagate to the parent table.


Solution

  • Normalize your store's state. If Product-Variant relationship is pure 1-n, the store's state can be:

    state: {
      name: 'some name',
      price: 'some price',
      variants: [
        { variantId: 'V1', ProductId: 'P1' },
        ...
      ],
      selectedVariant: {},
      products: [
        { productId: 'P1' },
        ...
      ]
    }
    

    Then with Vuex's action you can add an action to handle update both Variant and Product together:

    ..., // state goes above
    mutations: {
      ...
      [EDIT_PRODUCT] (args) => { ... }
    },
    actions: {
      [EDIT_PRODUCT_VARIANT] ({ commit, state }, editedComment) {
        // take extra data if need via state
        commit([EDIT_VARIANT], editedComment);
        commit([EDIT_PRODUCT], { productId: editedComment.ProductId })
      }
    }
    

    The point is to avoid data duplication and nested data as much as possible, while allowing data to be updated fast and efficiently.

    Read more about data normalization at normalizr