'What is wrong with my reselect function ? I dont get an output

I want to use reselect. I want to get my shopping cart by the ids.

reselect.ts

import { createSelector } from "reselect";
import { RootState } from "../store";

export const shoppingCarts = (state: RootState) => state.ShoppingCart;

export const getCartById = (state: any, id: string) => createSelector(
  shoppingCarts,
  state => state.find(cart => cart.product?.id === id)
);

Index.tsx

  const { product_id } = props;
  const shoppingCart = useSelector(state => getCartById(state, product_id));

  console.log(shoppingCart);

console log output

[Function memoized]

how can I get the output of my function (or the json value) ?

if I make this

shoppingCart()

then I get this

undefined is not an object (evaluating 'state.ShoppingCart')


Solution 1:[1]

Because getCartById is a selector factory function, NOT a selector. That's why you got [Function memoized] log when you called it inside useSelector.

Take a look at the doc How do I create a selector that takes an argument?.

provide input selectors that extract the arguments and forward them to the output selector for calculation

E.g.

const selectItemsByCategory = createSelector(
  [
    // Usual first input - extract value from `state`
    state => state.items,
    // Take the second arg, `category`, and forward to the output selector
    (state, category) => category
  ],
  // Output selector gets (`items, category)` as args
  (items, category) => items.filter(item => item.category === category)
)

So, It should be:

import { createSelector } from 'reselect';

export const shoppingCarts = (state) => state.carts;

export const getCartById = createSelector([shoppingCarts, (_, productId: string) => productId], (carts, productId) =>
  carts.find((cart) => cart.product?.id === productId),
);

Test

import { render } from '@testing-library/react';
import { renderHook } from '@testing-library/react-hooks';
import React from 'react';
import { Provider, useSelector } from 'react-redux';
import { combineReducers, createStore } from 'redux';
import { getCartById } from '.';

describe('72135522', () => {
  test('should pass', () => {
    const product_id = '1';
    function TestComp() {
      const cart = useSelector((state) => getCartById(state, product_id));
      console.log(cart);
      return null;
    }
    const rootReducer = combineReducers({
      carts: (state = [{ product: { id: '1' } }, { product: { id: '2' } }]) => state,
    });
    const store = createStore(rootReducer);
    render(
      <Provider store={store}>
        <TestComp />
      </Provider>,
    );
  });
});

The logs:

 console.log
    { product: { id: '1' } }

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1