Blog>
Snippets

Modular Redux Selectors for Reusability

Shows how to create and organize modular Redux selectors for efficient reusability across different components and features in an application.
// selectors.js
import { createSelector } from 'reselect';

// Assume state shape is:
// { products: { byId: {}, allIds: [] }, cart: { items: [] } }

// Simple selectors
const getProductsState = (state) => state.products;
const getCartState = (state) => state.cart;

// Composable selectors using reselect
c export const getProductsById = createSelector(
    getProductsState,
    (products) => products.byId
);
export const getAllProductIds = createSelector(
    getProductsState,
    (products) => products.allIds
);
export const getCartItems = createSelector(
    getCartState,
    (cart) => cart.items
);
This piece of code defines modular selectors for the pieces of the state associated with products and cart. It uses the 'reselect' library for memoization and composability.
// components/ProductList.js
import React from 'react';
import { useSelector } from 'react-redux';
import { getProductsById, getAllProductIds } from '../selectors';

const ProductList = () => {
    const productsById = useSelector(getProductsById);
    const allProductIds = useSelector(getAllProductIds);

    return (
        <ul>
            {allProductIds.map((id) => (
                <li key={id}>{productsById[id].name}</li>
            ))}
        </ul>
    );
};

export default ProductList;
This component 'ProductList' uses the modular selectors 'getProductsById' and 'getAllProductIds' to access the state. It demonstrates how a component can reuse selectors defined elsewhere.
// components/CartSummary.js
import React from 'react';
import { useSelector } from 'react-redux';
import { getCartItems } from '../selectors';

const CartSummary = () => {
    const items = useSelector(getCartItems);
    // Compute total number of items in cart
    const itemCount = items.reduce((count, item) => count + item.quantity, 0);

    return (
        <div>
            <h2>Cart Summary</h2>
            <p>Items in cart: {itemCount}</p>
        </div>
    );
};

export default CartSummary;
The 'CartSummary' component uses the 'getCartItems' selector to retrieve the cart items, showcasing the reusability and composability of selectors across different components.