E
E
evg_962018-02-27 16:43:31
React
evg_96, 2018-02-27 16:43:31

How to change data from one "duck" to another?

There is a "duck" cart (responsible for the cart). It handles the addition of goods to the cart, and in the state the cart module is stored, which stores the currently added goods to the cart.
There is a "duck" catalog (responsible for the catalog of goods). It processes a request for all products from the database (firebase). The state displays a catalog with all products. Each product has an addedToCart property (whether the product has been added to the cart).
Now it turns out that adding to the cart is processed in one place, and the property needs to be changed in another.
How to change the addedToCart state to true when adding a product? How to change the value in the database is clear, but how to change the state from one duck to another is not clear. Tell me please. Or specify a different logic of work, maybe I didn’t approach the cart correctly at all.
5a95607f1a4e5969576133.pngAdding an item to the cart in the "duck" 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()
    }
  });
};

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Anton Spirin, 2018-02-27
@evg_96

Why does the product have the addedToCart property at all ?
Imagine that you have or will have pagination in your application. You went back and forth and downloaded the products again. The keys will then be lost.
Make selectors checkIsProductAddedToCartSelector and isProductAddedToCartSelector . Let the first one return a function that takes the product id and returns true if the product is found in the basket store . The second one takes the id of the product and returns a boolean value if the product is found or not found in the cart store . Use reselect for this .
And add them tomapStateToProps in connect .
You can call it in a list like this:

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

In detail like this:
const mapStateToProps((state, ownProps) => ({
  isAddedToCart: isProductAddedToCartSelector(state, ownProps),
}));

export default connect(mapStateToProps)(ProductDetails);

Sample implementations of selectors:
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),
);

D
davidnum95, 2018-02-27
@davidnum95

You can change the state of the added product in the catalog reducer using the ADD_PRODUCT_TO_CART_SUCCESS action. Something like:

case ADD_PRODUCT_TO_CART_SUCCESS:
  return {
    ...state,
    entities: {
       ...state.entities,
       [action.payload.productUid]: {
           ...state.entities[action.payload.productUid],
           addedToCart: true,
       }
    }
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question