オブジェクトのコレクションを検索するための高位 Redux ライブラリ。 js-worker-search を利用した検索アルゴリズム。
bvaughn.github.io/redux-search でライブデモをチェックしてください。
または、NPM を使用して自分でインストールします。
npm install --save redux-search
この README では、redux-search について簡単に説明します。詳細については、API ドキュメントを参照してください。
redux-search はドキュメントのコレクションを検索し、結果をドキュメント ID のArray
として返します。書類そのものは返却されないので注意が必要です。これは、パフォーマンス上の理由から、実際の検索は Web ワーカー スレッドで実行されるためです。ドキュメントをシリアル化してやり取りすることを避けるために、redux-search は単にドキュメントの ID を渡します。
このため、各ドキュメントにはid
属性が含まれている必要があります。
redux-search は、リソースを検索するためのアクションと、検索結果と現在の検索テキストを取得するためのセレクターを提供します。次に、ストアでリソースの変更を監視し、必要に応じて検索結果を自動的に更新します。
redux-search は現在、Regenerator ランタイムに依存していることに注意してください。プロジェクトでは、そのランタイムを提供するためにbabel-polyfill
必要とすることをお勧めします。
redux-search は、検索可能なコレクションに対する変更をストアで監視し、検索インデックスを自動的に構築します。これを行うには、どのリソースを監視し、どのフィールドにインデックスを付けるかを指定するだけで済みます。
import { applyMiddleware , combineReducers , compose , createStore } from 'redux'
import { reducer as searchReducer , reduxSearch } from 'redux-search'
// Configure reducer to store state at state.search
// You can store it elsewhere but you will need to supply your own :searchStateSelector
const rootReducer = combineReducers ( {
search : searchReducer
// Your other reducers go here...
} )
// Compose :reduxSearch with other store enhancers
const enhancer = compose (
applyMiddleware ( ... yourMiddleware ) ,
reduxSearch ( {
// Configure redux-search by telling it which resources to index for searching
resourceIndexes : {
// In this example Books will be searchable by :title and :author
books : [ 'author' , 'title' ]
} ,
// This selector is responsible for returning each collection of searchable resources
resourceSelector : ( resourceName , state ) => {
// In our example, all resources are stored in the state under a :resources Map
// For example "books" are stored under state.resources.books
return state . resources . get ( resourceName )
}
} )
)
// Note: passing enhancer as the last argument to createStore requires redux@>=3.1.0
const store = createStore ( reducer , initialState , enhancer )
デフォルトでは、redux-search はすべての部分文字列に一致するインデックスを構築します。次のように、事前に構成された独自のsearchApi
パラメータをミドルウェアに提供することで、この動作をオーバーライドできます。
import { reduxSearch , SearchApi , INDEX_MODES } from 'redux-search'
// all-substrings match by default; same as current
// eg "c", "ca", "a", "at", "cat" match "cat"
const allSubstringsSearchApi = new SearchApi ( )
// prefix matching (eg "c", "ca", "cat" match "cat")
const prefixSearchApi = new SearchApi ( {
indexMode : INDEX_MODES . PREFIXES
} )
// exact words matching (eg only "cat" matches "cat")
const exactWordsSearchApi = new SearchApi ( {
indexMode : INDEX_MODES . EXACT_WORDS
} )
const finalCreateStore = compose (
// Other middleware ...
reduxSearch ( {
resourceIndexes : { ... } ,
resourceSelector : ( resourceName , state ) => state . resources . get ( resourceName ) ,
searchApi : allSubstringsSearchApi || prefixSearchApi || exactWordsSearchApi
} )
) ( createStore )
また、SearchApi コンストラクターにパラメーターを渡して、検索でテキストを単語に分割 (トークン化) する方法をカスタマイズしたり、検索をデフォルトの大文字と小文字を区別しないから大文字と小文字を区別するように変更したり、検索トークンでの一致を有効にしたりすることもできます ( AND から OR への検索フィルタリング):
import { reduxSearch , SearchApi } from 'redux-search'
const finalCreateStore = compose (
// Other middleware ...
reduxSearch ( {
resourceIndexes : { ... } ,
resourceSelector : ( resourceName , state ) => state . resources . get ( resourceName ) ,
searchApi : new SearchApi ( {
// split on all non-alphanumeric characters,
// so this/that gets split to ['this','that'], for example
tokenizePattern : / [^a-z0-9]+ / ,
// make the search case-sensitive
caseSensitive : true
// return results for documents containing ANY of the search terms.
// (by default results are only returned for documents containing ALL of the terms.)
// if true, results are sorted so that documents with more matching tokens come first.
matchAnyToken : true
} )
} )
) ( createStore )
redux-search は、コンポーネントを検索状態に簡単に接続するためのセレクターとアクションクリエーターを提供します。たとえば、 reselect
使用すると、次のようにコンポーネントを接続できます。
// Elsewhere, in a smart component module...
import { connect } from 'react-redux'
import { createSelector } from 'reselect'
import { createSearchAction , getSearchSelectors } from 'redux-search'
// :books is a map (Object or Immutable.Map) with ids as keys
// These ids correspond to :result returned by getSearchSelectors('books')
const books = state => state . getIn ( [ 'resources' , 'books' ] )
// :text is a selector that returns the text Books are currently filtered by
// :result is an Array of Book ids that match the current seach :text (or all Books if there is no search :text)
const {
text , // search text
result // book ids
} = getSearchSelectors ( {
resourceName : 'books' ,
resourceSelector : ( resourceName , state ) => state . resources . get ( resourceName )
} )
const selectors = createSelector (
[ result , books , text ] ,
( bookIds , books , searchText ) => ( {
bookIds ,
books ,
searchText
} )
)
const actions = {
searchBooks : createSearchAction ( 'books' )
}
export default connect ( selectors , actions ) ( YourConnectedComponent )
変更は変更ログで追跡されます。
redux-search は MIT ライセンスの下で利用できます。