我正在构建一个包含商品列表的购物车。用户可以更新每个项目的数量,从而调整项目的价格。同样在购物车的底部,应该有一个用户必须支付的所有价格的总总和。
我的问题是,如何获得所有更新的价格,将它们相加,并显示总。如何使总在用户更改每个项目的数量时进行自我更新?
React (项目):
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 (操作):
// 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):
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;
发布于 2018-07-30 03:29:05
您不需要使用不同的操作来更新总价格。每当你向购物车添加新商品时,你的状态都会改变,对吗?在这种情况下,您所需要做的就是编写一个util,如下所示:
// utils.js
export const totalPrice = (state) => {
const products = state.products;
const reducer = (currentTotal, product) => currentTotal + product.price;
return products.reduce(reducer);
};
然后,在您的容器中执行如下操作:
// 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
操作。
// 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的更多信息。
https://stackoverflow.com/questions/51583607
复制相似问题