Reselect - selector that invokes another selector?

前端 未结 4 1039
醉酒成梦
醉酒成梦 2021-02-05 07:14

I have a selector:

const someSelector = createSelector(
   getUserIdsSelector,
   (ids) => ids.map((id) => yetAnotherSelector(store, id),
);                        


        
4条回答
  •  天涯浪人
    2021-02-05 08:01

    A problem we faced when using reselect is that there is no support for dynamic dependency tracking. A selector needs to declare upfront which parts of the state will cause a recomputation.

    For example, I have a list of online user IDs, and a mapping of users:

    {
      onlineUserIds: [ 'alice', 'dave' ],
      notifications: [ /* unrelated data */ ]
      users: {
        alice: { name: 'Alice' },
        bob: { name: 'Bob' },
        charlie: { name: 'Charlie' },
        dave: { name: 'Dave' },
        eve: { name: 'Eve' }
      }
    }
    

    I want to select a list of online users, e.g. [ { name: 'Alice' }, { name: 'Dave' } ].

    Since I cannot know upfront which users will be online, I need to declare a dependency on the whole state.users branch of the store:

    This works, but this means that changes to unrelated users (bob, charlie, eve) will cause the selector to be recomputed.

    I believe this is a problem in reselect’s fundamental design choice: dependencies between selectors are static. (In contrast, Knockout, Vue and MobX do support dynamic dependencies.)

    We faced the same problem and we came up with @taskworld.com/rereselect. Instead of declaring dependencies upfront and statically, dependencies are collected just-in-time and dynamically during each computation:

    This allows our selectors to have a more fine-grained control of which part of state can cause a selector to be recomputed.

提交回复
热议问题