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.
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