'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 |