createStructuredSelector
这是一个方便的函数,简化了返回由选择器结果组成的对象的过程。
参数
名称 | 描述 |
---|---|
inputSelectorsObject | 由输入选择器组成的键值对。 |
selectorCreator? | 自定义的选择器创建函数。默认为 createSelector 。 |
返回值
一个被记忆化的结构化选择器。
类型参数
名称 | 描述 |
---|---|
InputSelectorsObject | input selectors 对象的形状。 |
MemoizeFunction | 用于创建结构化选择器的记忆化函数的类型。默认为 lruMemoize 。 |
ArgsMemoizeFunction | 用于记忆化传入生成的结构化选择器的参数的记忆化函数的类型。默认为 lruMemoize 。 |
示例
现代用例
- TypeScript
- JavaScript
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/modernUseCase.js
import { createSelector, createStructuredSelector } from 'reselect'
// 这个:
export const structuredSelector = createStructuredSelector(
{
todos: state => state.todos,
alerts: state => state.alerts,
todoById: (state, id) => state.todos[id]
},
createSelector
)
// 本质上与这个相同:
export const selector = createSelector(
[state => state.todos, state => state.alerts, (state, id) => state.todos[id]],
(todos, alerts, todoById) => {
return {
todos,
alerts,
todoById
}
}
)
在你的组件中:
- TypeScript
- JavaScript
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>
)
}
createStructuredSelector/MyComponent.jsx
import { structuredSelector } from 'createStructuredSelector/modernUseCase'
import { useSelector } from 'react-redux'
const MyComponent = ({ id }) => {
const { todos, alerts, todoById } = useSelector(state =>
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>()
:
- TypeScript
- JavaScript
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]
})
createStructuredSelector/withTypes.js
import { createStructuredSelector } from 'reselect'
export const createStructuredAppSelector = createStructuredSelector.withTypes()
const structuredAppSelector = createStructuredAppSelector({
// `state` 的类型被设置为 `RootState`,无需手动设置类型
todos: state => state.todos,
alerts: state => state.alerts,
todoById: (state, id) => state.todos[id]
})