Отправка не изменяющего объекта в состоянии Redux - PullRequest
0 голосов
/ 22 января 2020

Итак, я создаю приложение для электронной коммерции, и у меня есть два значения, сохраненные в избыточном состоянии для обработки корзины. Один из них представляет собой массив объектов, каждый из которых содержит два ключа для objectID и количества. Другой - это объект, содержащий информацию о продукте с идентификатором объекта в качестве ключа. Вот код моего действия / отправки.

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
            });
        };
    },

Действие определенно выполняется. Следующим будет мой редуктор.

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

Он также выполняется, и действительно, при проверке состояния productQuantity обновляется в состоянии, а products - нет. Я попробовал каждую конфигурацию определений на этом этапе и рву свои волосы. Помощь будет принята с благодарностью.

Что я могу подтвердить:

  • Правильные данные отправляются в редуктор.
  • Редуктор выполняется.
  • ProductQuantity корректно обновляется редуктором и имеет правильное значение.

Ответы [ 2 ]

0 голосов
/ 22 января 2020

Благодаря ответу маркериксона я пересмотрел свое действие, чтобы неизменно лечить состояние Redux, и проблема была решена. Вот мое обновленное действие для справки.

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 голосов
/ 22 января 2020

Первая проблема заключается в том, что вы изменяете существующее состояние перед отправкой действия, и изменяющее состояние запрещено в 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});
                }
            }

Любые изменения здесь productQuantity мутируют существующие данные в магазине Redux. Не делайте этого.

Я не совсем понимаю, что здесь происходит с products, потому что логика c немного сбивает с толку.

Мои предложения:

Сначала начните использовать наш новый официальный пакет Redux Toolkit . Он имеет функцию configureStore(), которая автоматически настраивает обнаружение случайных мутаций и будет выдавать ошибки, если вы будете мутировать.

Во-вторых, попытайтесь переместить все эти логи модификации c в ваш редуктор вместо того, чтобы делать это на стороне создания действия.

В-третьих, используйте Redux Toolkit createSlice API , который использует библиотеку Immer для того, чтобы вы могли писать "мутирующие" логики c в ваших редукторах и безопасно преобразует его в правильные неизменяемые результаты.

...