首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在Reactjs (使用redux/thunk)中,如何获取购物车中所有项目的总成本

在Reactjs (使用redux/thunk)中,如何获取购物车中所有项目的总成本
EN

Stack Overflow用户
提问于 2018-07-30 03:04:36
回答 1查看 535关注 0票数 -1

我正在构建一个包含商品列表的购物车。用户可以更新每个项目的数量,从而调整项目的价格。同样在购物车的底部,应该有一个用户必须支付的所有价格的总和。

我的问题是,如何获得所有更新的价格,将它们相加,并显示。如何使在用户更改每个项目的数量时进行自我更新?

React (项目):

代码语言:javascript
复制
class Item extends Component {
  constructor(props) {
    super(props);

    this.state = {
      quantity: 1,
      price: parseFloat(this.props.product.price.replace(/\$|£|/g, '')).toFixed(2)
    };

    this.onChangeHandler = this.onChangeHandler.bind(this);
  }

  onChangeHandler(event) {
    const target = event.target;
    this.props.updateSubtotal(this.props.product.price, event.target.value);
    this.setState((prevState, props) => ({
      quantity: target.value,
      price: props.subtotal
    }));
  }

  render() {
    const { product, index } = this.props;

    return (
      <li>
        <h3>{product.name}</h3>
        <Input
          onChange={this.onChangeHandler}
          name="product-quantity"
          value={this.state.quatity}
        />
        <span>
          {'$' + this.state.price}
        </span>
      </li>
    );
  }
}

const mapStateToProps = state => ({
  subtotal: state.products.subtotal
});

export default connect(mapStateToProps, { updateSubtotal })(Item);

Redux (操作):

代码语言:javascript
复制
// UPDATE TOTAL PRICE
export const updateTotal = result => dispatch => {

  // Don't what to do here. Or maybe there's a better solution...
  const newTotal = [];
  newTotal.push(result);

  return dispatch({
    type: UPDATE_TOTAL,
    total: newTotal
  });
};

// UPDATE ITEM PRICE BY QUANTITY
export const updateSubtotal = (price, multiplier) => dispatch => {
  const result = computePrice(price, multiplier);

  // Update cart total      
  dispatch(updateTotal(result));

  return dispatch({
    type: UPDATE_SUBTOTAL,
    subtotal: result
  });
};

Redux (Reducer):

代码语言:javascript
复制
const INITIAL_STATE = {
  total: [],
  subtotal: 1,
  products: [],
  loading: false
};

const productsReducer = (state = INITIAL_STATE, action) => {
  switch (action.type) {
    // Update item price
    case Types.UPDATE_SUBTOTAL:
      return {
        ...state,
        subtotal: action.subtotal
      };

    // Update total
    case Types.UPDATE_TOTAL:
      return {
        ...state,
        total: action.total // -> I'm stuck here
      };

    default:
      return state;
  }
};

export default productsReducer;
EN

回答 1

Stack Overflow用户

发布于 2018-07-30 03:29:05

您不需要使用不同的操作来更新总价格。每当你向购物车添加新商品时,你的状态都会改变,对吗?在这种情况下,您所需要做的就是编写一个util,如下所示:

代码语言:javascript
复制
// utils.js

export const totalPrice = (state) => {
    const products = state.products;
    const reducer = (currentTotal, product) => currentTotal + product.price;
    return products.reduce(reducer);
};

然后,在您的容器中执行如下操作:

代码语言:javascript
复制
// Cart.js

import React from 'react';
import { connect } from 'react-redux';

import { totalPrice } from './utils'; // or wherever else

const Cart = ({ total }) => (
    <div>
        {`Your total is ${total}`}
    </div>
);

const mapStateToProps = state => ({
    total: totalPrice(state),
});

export default connect(
    mapStateToProps,
)(Cart);

每次您向products添加内容时,价格都会自动更新。

** 编辑 **

正如您在评论中所要求的,如果您想将total保留在reducer中,这是另一种方法。请注意,您将不再需要updateTotal操作。

代码语言:javascript
复制
// reducers.js

const INITIAL_STATE = {
    total: 0, // note this is not an array.
    subtotal: 0,  // I also set this to 0 instead.
    products: [],
    loading: false
};

const productsReducer = ( state = INITIAL_STATE, action ) => {
    switch(action.type) {
    case Types.UPDATE_SUBTOTAL:
        const newSubtotal = action.subtotal;
        const newTotal = state.total + (newSubtotal - state.subtotal);
        return {
            ...state,
            subtotal: newSubtotal,
            total: newTotal,
        };
    }
    default:
        return state;
};

即使上面的方法有效,我还是建议您调度一个操作来更新products,而不是价格,并根据该操作更新所有相关的内容。如果你仔细想想,每当一个项目被添加到products中时,更新总价格/小计价格、数量等是有意义的。

还有一件事:我在impression spread syntax下,就像你在你的reducer中使用的一样,做浅拷贝。您需要小心处理存储在products数组中的内容,以免错误地更改旧状态;请记住,您总是希望返回新的状态对象。您可以阅读有关该here的更多信息。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51583607

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档