Redux/reselect 选择器函数参数解释?

Redux/reselect selector function arguments explanation?

我正在开发一个使用大量不可变重新选择的 Typescript 编写的代码库。我还没有使用过重新选择,但遇到了一个我不理解的例子:

export const panelsSelector: (
  order: Order,
  events: List<List<Event>>,
  adminRole: boolean,
  packageEvents: List<List<PackageEvent>>,
) => List<PanelProps> = createImmutableEqualSelector(
  (order: Order) => order,
  (order: Order, events: List<List<Event>>) => events,
  (order: Order, events: List<List<Event>>, adminRole: boolean) => adminRole,
  (order: Order, events: List<List<Event>>, adminRole: boolean, packageEvents: List<List<PackageEvent>>) => packageEvents,
  (order, events, adminRole, packageEvents) => List<PanelProps>([
      {
        content: <Events packageEvents={packageEvents}
                         events={events}
                 />
      },
      {
        content: <MyComponent  packages={order.get('packages')}
                               adminRole={adminRole}
                               packagesCount={order.get('noOfPackages')}/>
      },
)

如果我没看错,panelsSelector 被赋值了,我猜是一个匿名类型,它是一个函数。在这种情况下,我猜测 createImmutableEqualSelector returns 一个 returns List<PanelProps> 的函数。为了简化这样的事情:

const panelsSelector:(arg) => List<PanelProps> = createImmutableEqualSelector((arg) => List<PanelProps>)

在这个例子中我不明白的是为什么选择器需要将一个参数从它的前身添加到参数列表中?

  (order: Order) => order,
  (order: Order, events: List<List<Event>>) => events,
  (order: Order, events: List<List<Event>>, adminRole: boolean) => adminRole,
  (order: Order, events: List<List<Event>>, adminRole: boolean, packageEvents: List<List<PackageEvent>>) => packageEvents

如果我从第二个选择器的前导中删除参数:

(events: List<List<Event>>) => events

我收到打字稿错误:

Types of parameters 'state' and 'order' are incompatible.

那么,为什么这个选择器需要这样写呢? 到目前为止,我只看到过像这样的简单示例,我们从状态中获取数据:

const selectShopItems = state => state.shop.items

但是,我不明白前面的例子。如果订单不是状态,那么数据来自哪里?

当您调用 Reselect 选择器时,例如 selectThing(state, 2, 3, 4),Reselect 将使用相同的输入调用每个输入选择器:

const input1Result = inputSelector1(state, 2, 3, 4);
const input2Result = inputSelector2(state, 2, 3, 4);
const input3Result = inputSelector3(state, 2, 3, 4);
// etc

Reselect 然后将每个结果传递给最终的“输出选择器”:

const finalResult = outputFunction(input1Result, input2Result, input3Result);

因此,所有 输入函数将使用完全相同的参数调用。

有一个或两个输入选择器从 Redux state 中提取数据是很常见的,而且还提取一些额外的参数:

const selectItemId = (state, itemId) => itemId;

在这种情况下,编写 panelsSelector 的人决定不明确列出所有输入选择器的所有四个参数。没关系,因为 JS 允许您使用比实际需要更多的参数来调用函数——它们只需要正确排列(即,它们都应该期望 events 是第二个参数)。

我对这个特定的选择器有几点看法:

首先,没有必要明确指定 panelsSelector 的类型。 TS 会知道它是一个接受这些参数和 return 结果的函数。

其次,有一个 returns JSX 感觉的选择器......有点粗略?它会起作用,但我个人会尽量避免这种情况。我只想 return 只是一个数据结构,并将 JSX 部分保留在实际组件中。

请注意,最新版本的 Reselect (4.1.x) 也大大改进了 TS 类型。

最后,we recommend against using Immutable.js at all today with Redux,特别是考虑到我们的官方 Redux Toolkit 包是使用 Immer 进行不可变更新构建的。

您可能还想阅读 Deriving Data With Selectors 上的 Redux 文档页面。