跳到主要内容

createStructuredSelector

这是一个方便的函数,简化了返回由选择器结果组成的对象的过程。

参数

名称描述
inputSelectorsObject由输入选择器组成的键值对。
selectorCreator?自定义的选择器创建函数。默认为 createSelector

返回值

一个被记忆化的结构化选择器。

类型参数

名称描述
InputSelectorsObjectinput selectors 对象的形状。
MemoizeFunction用于创建结构化选择器的记忆化函数的类型。默认为 lruMemoize
ArgsMemoizeFunction用于记忆化传入生成的结构化选择器的参数的记忆化函数的类型。默认为 lruMemoize

示例

现代用例

createStructuredSelector/modernUseCase.ts
import { createSelector, createStructuredSelector } from 'reselect'

export interface RootState {
todos: {
id: number
completed: boolean
title: string
description: string
}[]
alerts: { id: number; read: boolean }[]
}

// 这个:
export const structuredSelector = createStructuredSelector(
{
todos: (state: RootState) => state.todos,
alerts: (state: RootState) => state.alerts,
todoById: (state: RootState, id: number) => state.todos[id]
},
createSelector
)

// 本质上与这个相同:
export const selector = createSelector(
[
(state: RootState) => state.todos,
(state: RootState) => state.alerts,
(state: RootState, id: number) => state.todos[id]
],
(todos, alerts, todoById) => {
return {
todos,
alerts,
todoById
}
}
)

在你的组件中:

createStructuredSelector/MyComponent.tsx
import type { RootState } from 'createStructuredSelector/modernUseCase'
import { structuredSelector } from 'createStructuredSelector/modernUseCase'
import type { FC } from 'react'
import { useSelector } from 'react-redux'

interface Props {
id: number
}

const MyComponent: FC<Props> = ({ id }) => {
const { todos, alerts, todoById } = useSelector((state: RootState) =>
structuredSelector(state, id)
)

return (
<div>
下一个待办事项是:
<h2>{todoById.title}</h2>
<p>描述:{todoById.description}</p>
<ul>
<h3>所有其他待办事项:</h3>
{todos.map(todo => (
<li key={todo.id}>{todo.title}</li>
))}
</ul>
</div>
)
}

Simple Use Case

const selectA = state => state.a
const selectB = state => state.b

// 下面选择器中的结果函数
// 只是从输入选择器构建一个对象
const structuredSelector = createSelector(selectA, selectB, (a, b) => ({
a,
b
}))

const result = structuredSelector({ a: 1, b: 2 }) // 将产生 { x: 1, y: 2 }

createStructuredSelector接受一个对象,该对象的属性是输入选择器,并返回一个结构化选择器。结构化选择器返回一个对象,该对象具有与inputSelectorsObject参数相同的键,但是选择器被其值替换。

const selectA = state => state.a
const selectB = state => state.b

const structuredSelector = createStructuredSelector({
x: selectA,
y: selectB
})

const result = structuredSelector({ a: 1, b: 2 }) // 将产生 { x: 1, y: 2 }

结构化选择器可以嵌套:

const nestedSelector = createStructuredSelector({
subA: createStructuredSelector({
selectorA,
selectorB
}),
subB: createStructuredSelector({
selectorC,
selectorD
})
})

定义预设类型的 createStructuredSelector

从 Reselect 5.1.0 开始,你可以创建一个预设 state 类型的 createStructuredSelector。这允许你一次性设置 state 类型,从而无需在每次调用 createStructuredSelector 时指定它。

要做到这一点,你可以调用 createStructuredSelector.withTypes<StateType>()

createStructuredSelector/withTypes.ts
import { createStructuredSelector } from 'reselect'

export interface RootState {
todos: { id: number; completed: boolean }[]
alerts: { id: number; read: boolean }[]
}

export const createStructuredAppSelector =
createStructuredSelector.withTypes<RootState>()

const structuredAppSelector = createStructuredAppSelector({
// `state` 的类型被设置为 `RootState`,无需手动设置类型
todos: state => state.todos,
alerts: state => state.alerts,
todoById: (state, id: number) => state.todos[id]
})