在爲何咱們須要reselect 咱們闡述了 reselect的必要性。
簡單回顧一下:javascript
class UnusedComp extends Component { render() { const { a, b, c, fab, hbc, gac, uabc } = this.props return ( <div> <h6>{a}</h6> <h6>{b}</h6> <h6>{c}</h6> <h6>{fab}</h6> <h6>{hbc}</h6> <h6>{gac}</h6> <h6>{uabc}</h6> </div> ) } }
其中fab = f(a, b), hbc = h(b, c), gac = g(a, c), uabc = u(a, b, c)。 對於這樣的組件,咱們只須要存儲狀態a, b, c, 對於fab, hbc, gac, uabc這種能夠徹底經過現有 狀態推導出來的,稱爲‘衍生屬性’。 咱們應該只存最小集合的狀態,這樣方便咱們更新狀態, 保證數據層正確性等 不少好處。
也正如爲何咱們須要reselect指出, 這樣容易帶來沒有意義的函數執行(具體看原文)。 解決方法以下:java
// // import { createSelector } from 'reselect' import { f, h, g, u } from './xx' fSelector = createSelector( a => state.a, b => state.b, (a, b) => f(a, b) ) hSelector = createSelector( b => state.b, c => state.c, (b, c) => h(b, c) ) gSelector = createSelector( a => state.a, c => state.c, (a, c) => g(a, c) ) uSelector = createSelector( a => state.a, b => state.b, c => state.c, (a, b, c) => u(a, b, c) ) ... function mapStateToProps(state) { const { a, b, c } = state return { a, b, c, fab: fSelector(state), hbc: hSelector(state), gac: gSelector(state), uabc: uSelector(state) } }
用過mobx的,不會忘記@compute的簡潔, 那麼redux生態下有替代reselct的簡潔的方案嗎? 衍生
屬性是能夠經過基本屬性推導出來的, 而且相同的基本屬性必定推導出相同的值。
如fab = f(a, b)。 只要a,b相同,那麼fab必定相同。 基於這一點,咱們能夠有:react
function x(func) { let oldargs = [] let oldresult = null return function(...args) { if(equal(oldargs, args)) { // equal? return oldresult } oldargs = args oldresult = func(...args) return oldresult } } /// now we use function f(a, b) { ... } export const xf = x(f)
函數x賦予了 衍生函數 記憶的功能,就像reselect同樣, 書寫起來卻方便了不少。
得益於redux在equal(oldargs, args)
的時候, 咱們能夠直接使用 === 來比較參數git
能夠說函數x 就是簡版的repure。 github地址github
repure 提供3個方法 repureCreator(cacheSize, equalityCheck), repure, repureOneCacheCreator(equalityCheck)npm
函數repureCreator 返回一個repure, 能夠緩存cacheSize個結果。 在判斷入參是否相同的時候使用 equalityCheck。
默認的 equalityCheck 是:redux
function defaultEqualityCheck(a, b) { return a === b }
另外提供一個 shallowEqual: import { shallowEqual } from 'repure'
segmentfault
大部分狀況下,你應該使用這個方法。 這個和你使用reselct的createSelector的效果是同樣的, 使用===
比較相等, cacheSize是1。
repure接受一個pure function, 返回這個方法的 緩存版本緩存
repureCreator 在cacheSize=1 時的優化版本函數
另外提供一個 batchRepure(obj, repure) 方法。 能夠批量repure。
repure重寫開頭的例子
首先安裝npm install repure --save
import repure, { batchRepure } from 'repure' import * as allfunc from './xx' const { f, h, g, u } = batchRepure(allfunc, repure) ... function mapStateToProps(state) { const { a, b, c } = state return { a, b, c, fab: f(a, b), hbc: h(b, c), gac: g(a, c), uabc: u(a, b, c) } }