2017-04-07 45 views
4

當我將更多選擇器組合在一起時,我發現我正在重新定義選擇器的定義位置。例如,如何在組合選擇器時忽略重新選擇器的排序

export const selectNav = state => state.nav; 
export const selectPage = state => state.page; 

export const selectNavAndPage = createSelector([ 
    selectNav, 
    selectPage, 
], (nav, page) => { 

}); 

export const selectFoo = state => state.foo; 

export const selectNavAndPageAndFoo = createSelector([ 
    selectNavAndPage, 
    selectFoo, 
], (navAndPage, foo) => { 

}); 

這是一個簡單的例子,但我不能低於selectNavAndPageAndFoo定義selectNavAndPage。隨着更多的選擇器組合和選擇器的選擇器組合,我需要確保在使用它們之前,所有的子選擇器都在頂部定義。

有沒有一些方法來創建這些選擇器,使排序無關緊要?

回答

1

我敢肯定這只是關係到ES6 const關鍵字的工作原理。使用const時,變量在該行之前不存在,因此如果要引用const變量,則需要在之後編寫代碼的變量聲明。通過var,所有變量都託管在範圍的頂部。

因此,要麼使用var,以便您可以不按順序參考,或繼續使用const,並按正確的順序定義每個功能的用法和參考。

+0

不幸的是,在我的示例中將const更改爲var將不起作用。該變量會被提升,但是當createSelector()被調用時,那麼被傳入的未定義變量將被傳入。 – epikhighs

2

我很擔心同樣的問題,我創建了這個npm模塊define-selectors。這是一個模塊,它延遲選擇器的定義來解決選擇器定義問題的順序,併爲其添加其他功能。它還沒有穩定下來,但我會在我的項目中使用它以使其穩定並得到改進。

欲瞭解更多信息,請登錄github page並閱讀自述文件和源文件。

0

如果你不介意一點點額外的輸入,這裏是另一種方法,需要定義一個包裝createSelector功能,並採取功能提升的優勢「CMS」效用函數:

import {createSelector} from 'reselect'; 

// create memoized selector 
function cms(ctx, ...args) { 
    if (!ctx.selector) ctx.selector = createSelector(...args); 
    return ctx.selector; 
} 

// define the selectors out of order... 

export function getBaz(state) { 
    return cms(
     getBaz // the function itself as context 
     , getBar 
     , bar => bar.baz 
    )(state); 
} 

export function getBar(state) { 
    return cms(
     getBar 
     , getFoo 
     , foo => foo.bar 
    )(state); 
} 

export function getFoo(state) { 
    return state.foo; 
} 

這不是像簡單地按順序定義選擇器一樣優雅,但也許別人可以採取這種想法並改進它。