Jadi saya sedang membangun aplikasi e-niaga, dan saya memiliki dua nilai yang disimpan dalam status redux untuk menangani keranjang. Salah satunya adalah array objek, yang masing-masing berisi dua kunci untuk objectID dan kuantitas. Yang lainnya adalah objek yang berisi informasi produk dengan objectID mereka sebagai kunci. Inilah kode untuk tindakan/pengiriman saya.

addToCart: (product) => {
        return (dispatch, getState) => {
            const {productQuantity, storeSelected, products, storeKeys} = getState().Ecommerce;
            const UPC = product.UPC;
            let newQuant = 1;
            let newProducts;
            for(var p in productQuantity) {
                if (productQuantity[p].UPC === UPC) {
                    newProducts = products
                    newQuant += productQuantity[p].quantity;
                    productQuantity[p] = ({UPC, quantity: newQuant});
                }
            }
            if (!newProducts) {
                console.log("not found")
                productQuantity.push({UPC, quantity: 1});
                newProducts = {
                    ...products,
                    [UPC]: {
                        ...product,
                        price: product.stores[storeKeys[storeSelected]].price,
                        fromStore: storeKeys[storeSelected],
                    }
                }
            }
            dispatch({
                type: actions.CHANGE_CART,
                products: newProducts,
                productQuantity
            });
        };
    },

Aksi pasti berjalan. Selanjutnya adalah peredam saya.

case actions.CHANGE_CART:
    console.log('This runs')
    console.log(action.products);
    console.log(action.productQuantity);
    return {
        ...state,
        products: action.products,
        productQuantity: action.productQuantity
    };

Itu juga dijalankan, dan memang ketika memeriksa status, productQuantity diperbarui dalam status tetapi produk tidak. Saya sudah mencoba setiap konfigurasi definisi pada saat ini dan saya merobek rambut saya. Bantuan akan sangat dihargai.

Yang bisa saya konfirmasi:

  • Data yang benar sedang dikirim ke peredam.
  • Pereduksi dijalankan.
  • ProductQuantity diperbarui oleh peredam dengan benar dan memiliki nilai yang benar.
0
Stuart Johnson 22 Januari 2020, 20:18

2 jawaban

Jawaban Terbaik

Masalah pertama adalah Anda mengubah status yang ada sebelum mengirimkan tindakan, dan status mutasi dilarang di Redux:

const {productQuantity, storeSelected, products, storeKeys} = getState().Ecommerce;
            const UPC = product.UPC;
            let newQuant = 1;
            let newProducts;
            for(var p in productQuantity) {
                if (productQuantity[p].UPC === UPC) {
                    newProducts = products
                    newQuant += productQuantity[p].quantity;
                    productQuantity[p] = ({UPC, quantity: newQuant});
                }
            }

Setiap perubahan pada productQuantity di sini mengubah data yang ada di toko Redux. Jangan lakukan itu.

Saya tidak begitu jelas tentang apa yang terjadi dengan products di sini, karena logikanya terasa agak membingungkan.

Saran saya:

Pertama, mulai gunakan paket Redux Toolkit resmi kami. Ini memiliki fungsi configureStore() yang secara otomatis mengatur deteksi untuk mutasi yang tidak disengaja, dan akan menimbulkan kesalahan jika Anda bermutasi.

Kedua, coba pindahkan semua logika modifikasi ini ke peredam Anda, alih-alih melakukannya di sisi pembuatan tindakan.

Ketiga, gunakan createSlice API dari Redux Toolkit, yang menggunakan library Immer untuk untuk memungkinkan Anda menulis logika "bermutasi" di reduksi Anda dan dengan aman mengubahnya menjadi hasil yang diperbarui secara permanen.

0
markerikson 22 Januari 2020, 17:25

Berkat respons markerikson, saya merevisi tindakan saya untuk memperlakukan status Redux secara permanen dan masalahnya telah teratasi. Inilah tindakan saya yang diperbarui untuk referensi.

addToCart: (product) => {
        return (dispatch, getState) => {
            const {productQuantity, storeSelected, products, storeKeys} = getState().Ecommerce;
            const UPC = product.UPC;

            let newQuantity = 1;
            for(var p in productQuantity) {
                if (productQuantity[p].UPC === UPC) {
                    newQuantity += productQuantity[p].quantity;
                }
            }

            dispatch({
                type: actions.CHANGE_CART,
                products: {
                    ...products,
                    [UPC]: {
                        ...product,
                        price: product.stores[storeKeys[storeSelected]].price,
                        fromStore: storeKeys[storeSelected],
                    }
                },
                productQuantity: productQuantity
                    .filter((value, index) => value.UPC !== product.UPC)
                    .concat([{UPC, quantity: newQuantity}])
            });
        };
    },
0
Stuart Johnson 22 Januari 2020, 18:07