josepot / redux-views

Like Reselect but with better support for shared-selectors

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Best practice to reuse parametric selectors in arrays

martinkutter opened this issue · comments

What is the best practice (if it is possible) to reuse the getCarView selector in the following example?

reduxStore = {
    defaultFront: "defaultFront.jpg",
    defaultBack: "defaultBack.jpg",
    view: "front",
    favorits: ["uid1", "uid2"],
    cars: {
        "uid1": {
            front: "front.jpg",
            back: "back.jpg",
        },
        "uid2": {},
        ...
    }
}

const getUidFromProps = createIdSelector(props => props.uid);
const getView = state => state.view;
const getCars = state => state.cars;
const getDefaultBack = state => state.defaultBack;
const getDefaultFront = state => state.defaultFront;
const getFavorits = state => state.favorits;

const getCar = createSelector(
    [getUidFromProps, getCars],
    (uid, cars) => cars[uid]
);

const getCustomCarFront = createSelector([getCar], car => car.front);
const getCustomCarBack = createSelector([getCar], car => car.back);

const getCustomCarView = createSelector(
    [getCustomCarFront, getCustomCarBack, getView],
    (front, back, view) => view === "front" ? front : back
);
const getDefaultCarView = createSelector(
    [getDefaultBack, getDefaultFront, getView],
    (front, back, view) => view === "front" ? front : back
);
const getCarView = createSelector(
    [getCustomCarView, getDefaultCarView],
    (customView, defaultView) => customView || defaultView
);

const getViewsOfFavoritCars = createSelector(
    [getFavorits], 
    (favorits) => favorits.map(uid => {
        // reuse "getCarView" with given "uid"
    })
);

Thanks in advance

After rethinking about this situation with a colleague, it is the same as described in #28.
Unfortunately without good caching...

reduxStore = {
    defaultFront: "defaultFront.jpg",
    defaultBack: "defaultBack.jpg",
    view: "front",
    favorits: ["uid1", "uid2"],
    cars: {
        "uid1": {
            front: "front.jpg",
            back: "back.jpg",
        },
        "uid2": {},
        ...
    }
}

const identity = x => x;
const getUidFromProps = createIdSelector(props => props.uid);
const getView = state => state.view;
const getCars = state => state.cars;
const getDefaultBack = state => state.defaultBack;
const getDefaultFront = state => state.defaultFront;
const getFavorits = state => state.favorits;

const getCar = createSelector(
    [getUidFromProps, getCars],
    (uid, cars) => cars[uid]
);

const getCustomCarFront = createSelector([getCar], car => car.front);
const getCustomCarBack = createSelector([getCar], car => car.back);

const getCustomCarView = createSelector(
    [getCustomCarFront, getCustomCarBack, getView],
    (front, back, view) => view === "front" ? front : back
);
const getDefaultCarView = createSelector(
    [getDefaultBack, getDefaultFront, getView],
    (front, back, view) => view === "front" ? front : back
);
const getCarView = createSelector(
    [getCustomCarView, getDefaultCarView],
    (customView, defaultView) => customView || defaultView
);

const getViewsOfFavoritCars = createSelector(
    [identity, getFavorits], 
    (state, favorits) => favorits.map(uid => getCarView(state, { uid })
);

Or is there any better solution?