reselect中createSelector的用法及github代码解读
reselect
是一个redux中间件,github上有对应的文档:https://github.com/reduxjs/reselect
createSelector的使用例程如下:
import { createSelector } from 'reselect'
const shopItemsSelector = state => state.shop.items
const taxPercentSelector = state => state.shop.taxPercent
const subtotalSelector = createSelector(
shopItemsSelector,
items => items.reduce((subtotal, item) => subtotal + item.value, 0)
)
const taxSelector = createSelector(
subtotalSelector,
taxPercentSelector,
(subtotal, taxPercent) => subtotal * (taxPercent / 100)
)
const totalSelector = createSelector(
subtotalSelector,
taxSelector,
(subtotal, tax) => ({ total: subtotal + tax })
)
const exampleState = {
shop: {
taxPercent: 8,
items: [
{ name: 'apple', value: 1.20 },
{ name: 'orange', value: 0.95 },
]
}
}
console.log(subtotalSelector(exampleState)) // 2.15
console.log(taxSelector(exampleState)) // 0.172
console.log(totalSelector(exampleState)) // { total: 2.322 }
看作者起名不难看出这是一个算总价,税费及扣税后价格的例程。
先从例程的数据部分exampleState
看起,这是一个对象,exampleState.shop.taxPercent
表示税率,本质数值8。exampleState.shop.items
是一个数组,exampleState.shop.items.value
表示每个商品的价格。
从例程代码末尾处看到createSelector
函数调用后并不会直接赋值,只是创建了一个新的方法,将数据作为参数输入这个新的方法,然后由新的方法再去调用createSelector
才会生效。
拿第一个函数当做例子来说:
const shopItemsSelector = state => state.shop.items
const subtotalSelector = createSelector(
shopItemsSelector,
items => items.reduce((subtotal, item) => subtotal + item.value, 0)
)
console.log(subtotalSelector(exampleState)) // 2.15
createSelector
创建了一个subtotalSelector
方法,subtotalSelector
方法传入exampleState
作为参数,createSelector
本身也可以传递无限多个函数作为参数,假设传递了N个函数,前N-1个函数只有一个参数,那就是createSelector
创建的subtotalSelector
方法的参数,本例中就是exampleState
。最后一个函数有N-1个参数,这N-1个参数就是前N-1个函数的返回值。本例中只有一个参数。
首先exampleState
传递给subtotalSelector
方法,继而传递给shopItemsSelector
的state
参数,返回exampleState.shop.items
数组,并传递给createSelector
函数的第二个参数对应的函数,最后会传递到items
,调用reduce
方法实现对exampleState.shop.items.value
的累加。最终的到1.20+0.95=2.15。