@evg_96

Как изменить данные из одной «утки» в другой?

Есть "утка" cart (отвечает за корзину). В ней обрабатывается добавление товара в корзину, и в состоянии хранится модуль cart, в котором хранятся текущие добавленные товары в корзину.

Есть "утка" catalog (отвечает за каталог товаров). В ней обрабатывается запрос всех товаров из БД (firebase). В состоянии отображается catalog со всеми товарами. У каждого товара есть свойство addedToCart (добавлен ли товар в корзину).

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

Как изменить addedToCart в состоянии на true, при добавлении товара? Как изменить значение в БД понятно, а вот как изменить состояние из одной утки в другой, не ясно. Подскажите пожалуйста. Либо укажите иную логику работы, возможно я вообще не правильно подошел в работе с корзиной.
5a95607f1a4e5969576133.pngДобавление товара в корзину в "утке" cart:
// ...
case ADD_PRODUCT_TO_CART_SUCCESS: {
  return state.setIn(["entities", payload.productUid], new ProductRecord(payload.product));
}
// ...

export const addProductToCartSaga = function * (action) {
  const { productUid } = action.payload;

  const productRef = firebase.database().ref(`catalog/${productUid}`);
  const product = yield call([productRef, productRef.once], "value");

  yield put({
    type: ADD_PRODUCT_TO_CART_SUCCESS,
    payload: {
      productUid,
      product: product.val()
    }
  });
};
  • Вопрос задан
  • 111 просмотров
Решения вопроса 1
rockon404
@rockon404
Frontend Developer
Зачем вообще в товаре свойство addedToCart?
Представьте, что у вас в приложении есть или будет пагинация. Вы перешли вперед-назад и загрузили товары заново. Ключи при этом будут потеряны.

Сделайте селекторы checkIsProductAddedToCartSelector и isProductAddedToCartSelector. Первый пусть возвращает функцию принимающую id товара и возвращающую true если товар найден в store корзины. Второй пусть принимает id товара и возвращает булево значение, если товар найден или не найден в store корзины. Используйте для этого reselect.
И добавляйте их в mapStateToProps в connect.
В списке можно вызывать так:
const ProductsList = ({
  productsList,
  checkIsProductAddedToCart,
}) => (
  <ul>
    {productsList.map(product => (
      <Product
        addedToCart={checkIsProductAddedToCart(product.id)}
        product={product}
      />
    ))}
  </ul>
);

const mapStateToProps(state => ({
  productsList: productListSelector(state),
  checkIsProductAddedToCart: checkIsProductAddedToCartSelector(state),
}));

export default connect(mapStateToProps)(ProductsList);

В детализации так:
const mapStateToProps((state, ownProps) => ({
  isAddedToCart: isProductAddedToCartSelector(state, ownProps),
}));

export default connect(mapStateToProps)(ProductDetails);


Примерные реализации селекторов:
import { createSelector } from 'reselect';

const cartSelector = state => state.cart;

const cartProductsSelector = createSelector(
  cartSelector,
  cart => cart.products,
);

// возвращает функцию, принимающую id, которую можно использовать при построении списков
const checkIsProductAddedToCartSelector = createSelector(
  cartProductsSelector,
  products => id => products.some(product => product.id === id),
);

const productIdSelector = (_, props) => props.product.id;

// возвращает булево значение, важно чтобы в компоненте было свойство product
const isProductAddedToCartSelector = createSelector(
  cartProductsSelector,
  productIdSelector,
  (products, id) => products.some(product => product.id === id),
);
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@davidnum95
Можно в редьюсере каталога на экшен ADD_PRODUCT_TO_CART_SUCCESS менять состояние добавленного товара. Что то типа:
case ADD_PRODUCT_TO_CART_SUCCESS:
  return {
    ...state,
    entities: {
       ...state.entities,
       [action.payload.productUid]: {
           ...state.entities[action.payload.productUid],
           addedToCart: true,
       }
    }
}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через TM ID
Похожие вопросы