reduxjs / reselect

Selector library for Redux
MIT License
19.03k stars 671 forks source link

Problem of not getting result value when using currySelector by mapping another currySelector #728

Open dekim1028 opened 1 month ago

dekim1028 commented 1 month ago

https://reselect.js.org/faq/#how-can-i-make-a-curried-selector

It was developed with reference to the above document.

export const currySelector = <State, Result, Params extends readonly any[], AdditionalFields>(
    selector: ((state: State, ...args: Params) => Result) & AdditionalFields,
) => {
    const curriedSelector = (...args: Params) => {
        return (state: State) => {
            return selector(state, ...args);
        };
    };
    return Object.assign(curriedSelector, selector);
};
export class TestSelector {

  static readonly selectTestA = currySelector(
          createSelector(
              [
                  RootSelector.selectTest,
                  (_: ReduxStoreInterface, testId: number) => testId,
              ],
              (state, testId) =>{
                   console.log("call selectTestA");
                   return testId;
               }
          ),
      );

  static readonly selectTestB = currySelector(
          createSelector(TestSelector.selectTestA,
              (state) => {
                  console.log(">>>>> ", state);
          return {myTest: state};
         }
          ),
  );
}
const myTest = useSelector(TestSelector.selectTestB(1));

I expected the log to remain like this "call selectTestA" ">>>>> 1"

But in reality it is recorded like this ">>>>> undefined"

selectTestA doesn't seem to be called If I remove currySelector from selectTestA, it works normally. What is the reason? I wonder if a selector using currySelector cannot be called from another selector.

aryaemami59 commented 1 month ago

I wonder if a selector using currySelector cannot be called from another selector.

Your assumption is correct. In selectTestB you are re-currying an already curried selector. Instead you can do something like this:

export class TestSelector {

  static readonly selectTestA = 
          createSelector(
              [
                  RootSelector.selectTest,
                  (_: ReduxStoreInterface, testId: number) => testId,
              ],
              (state, testId) =>{
                   console.log("call selectTestA");
                   return testId;
               }
          );

  static readonly selectTestB = currySelector(
          createSelector(TestSelector.selectTestA,
              (state) => {
                  console.log(">>>>> ", state);
          return {myTest: state};
         }
          ),
  );
}