Recently, I start to learn reselect
, and try to use it to my project.
But, I'm doubtful about where should I put the code that calculates the derived data.
Below is my code snippet, I think I put formatDate
calcDayLeftFromNow
setDeriveData
logic to my reducer
will also be fine.
I do the derive data calculate in my reducer
will also be fine.
If I do this, it seems there is no reason to use reselect
.
function formatDate(millisecond) {
let d = new Date(millisecond);
let dateArr = [d.getFullYear(), d.getMonth() + 1, d.getDate()];
let date = dateArr.join('.');
return date;
}
function calcDayLeftFromNow(endTimeNum) {
const timeDiff = endTimeNum - new Date().getTime();
const daysDiff = Math.ceil(timeDiff / (1000 * 3600 * 24));
return daysDiff;
}
function setDeriveData(coupons) {
return Object.values(coupons).map((coupon, index) => {
coupon.startDate = formatDate(coupon.startTimeNum);
coupon.endDate = formatDate(coupon.endTimeNum);
coupon.dayLeft = calcDayLeftFromNow(coupon.endTimeNum);
return coupon;
});
}
const mapStateToProps = state => {
const { coupons, current_tab, result, page } = state.yao_coupon;
const newCoupons = setDeriveData(coupons);
return {
coupons: newCoupons,
current_tab,
result,
page
};
};
It's common to put your selector's code in your container component. Or if you don't want to split container from presentational, just put it in your component.
Selectors' role is to compute derived data from the state (store).
Whereas reducers specify how the application's state changes in response to an action.
So they serve a very different role in your app.
In the Reselect readme, they're putting everything in one file just to showcase its use in the simplest way.
Here is a common folder structure that might help you make sense of this:
Some people choose to put the selectors in a separate file. But it's up to you to decide. For example, you can put your selector in your container component and only move it to a separate file if it gets big. Another reason to move it to a separate file is in the event you need that same selector throughout parts of the app. (credits: @kwelch)
Edit
Calculating the derived price in your reducer will make it highly coupled with the api call, and you won't be able to use the dispatched action elsewhere. My suggestion is to move this calculation out of the reducer and calculate the
derivedPrice
before dispatching the action.