处理空数组结果
为了减少重新计算,当 array.filter
或类似方法结果为空数组时,使用预定义的空数组。
所以你可以有像这样的模式:
- TypeScript
- JavaScript
handling-empty-array-results/firstPattern.ts
import { createSelector } from 'reselect'
export interface RootState {
todos: {
id: number
title: string
description: string
completed: boolean
}[]
}
const EMPTY_ARRAY: [] = []
const selectCompletedTodos = createSelector(
[(state: RootState) => state.todos],
todos => {
const completedTodos = todos.filter(todo => todo.completed === true)
return completedTodos.length === 0 ? EMPTY_ARRAY : completedTodos
}
)
handling-empty-array-results/firstPattern.js
import { createSelector } from 'reselect'
const EMPTY_ARRAY = []
const selectCompletedTodos = createSelector([state => state.todos], todos => {
const completedTodos = todos.filter(todo => todo.completed === true)
return completedTodos.length === 0 ? EMPTY_ARRAY : completedTodos
})
或者为了避免重复,你可以创建一个包装函数并重用它:
- TypeScript
- JavaScript
handling-empty-array-results/fallbackToEmptyArray.ts
import { createSelector } from 'reselect'
import type { RootState } from './firstPattern'
const EMPTY_ARRAY: [] = []
export const fallbackToEmptyArray = <T>(array: T[]) => {
return array.length === 0 ? EMPTY_ARRAY : array
}
const selectCompletedTodos = createSelector(
[(state: RootState) => state.todos],
todos => {
return fallbackToEmptyArray(todos.filter(todo => todo.completed === true))
}
)
handling-empty-array-results/fallbackToEmptyArray.js
import { createSelector } from 'reselect'
const EMPTY_ARRAY = []
export const fallbackToEmptyArray = array => {
return array.length === 0 ? EMPTY_ARRAY : array
}
const selectCompletedTodos = createSelector([state => state.todos], todos => {
return fallbackToEmptyArray(todos.filter(todo => todo.completed === true))
})
这样,如果 result function 连续两次返回空数组,你的组件将不会因为稳定的空数组引用而重新渲染:
const completedTodos = selectCompletedTodos(store.getState())
store.dispatch(addTodo())
console.log(completedTodos === selectCompletedTodos(store.getState())) //=> true