Reputation: 33
I'm trying to combine two separate prices into one total price. I have the two individual price states stored and correctly updating using independent reducers, but I need a way to combine these two dynamic values into a third, total price state.
import React, {useState} from "react";
import { useSelector, useDispatch } from "react-redux";
const planPrice = useSelector(state => state.planPrice);
const repairPrice = useSelector(state => state.repairPrice);
//Use the state hook to store the Total Price
const [totalPrice, setTotalPrice] = useState(0);
const [items, setItems] = useState([]);
function addItem (newItem) {
setItems((prevItems) => {
return [...prevItems, newItem];
});
//Update the Plan Price
if ({plan}.plan === "Premium") {
dispatch(addItemPremium());
} else if ({plan}.plan === "Basic") {
dispatch(addItemBasic());
}
//Update the Repair Price
if (newItem === "Small Chip") {
dispatch(addSmallChip());
} else if (newItem === "Big Chip") {
dispatch(addBigChip());
}
// //Update the Total Price
setTotalPrice({planPrice} + {repairPrice});
}
Is this even possible using Redux, or am I going about this the wrong way?
Upvotes: 1
Views: 762
Reputation: 16576
If you have derived state, you should consider using selectors. These are functions that take state as an argument and return a derived state value.
For example:
function totalPrice(state) {
return state.price1 + state.price2;
}
If you need to use this in mapStateToProps
, you can do so as follows:
const mapStateToProps = state => ({
price: totalPrice(state)
})
If you're using hooks, you can use the useSelector
hook:
const price = useSelector(totalPrice);
There are libraries (e.g., reselect) that will help you create composable selectors with caching for efficiency.
Note that the reason you should use selectors versus storing redundant state, as you may have intuited, is that redundant state can get out of sync and then you're hosed. But if you have a function that computes the total price, it'll always be in sync with the individual state parts.
Upvotes: 3