diff --git a/README.md b/README.md index 08bfb55..47c6229 100644 --- a/README.md +++ b/README.md @@ -15,21 +15,20 @@ npm install --save react-use-flexsearch ## API ```js -useFlexSearch(query: String, index: Index! | String!, store: Object!, options: Object) => Object[] +useFlexSearch(query: String | Object, index: Index! | String!, options: Object) => Object[] ``` -The `useFlexSearch` [hook][hooks] takes your search query, index, and store and -returns results as an array. Searches are memoized to ensure efficient -searching. +The `useFlexSearch` [hook][hooks] takes your search query, index, and search +options and returns results as an array. Searches are memoized to ensure +efficient searching. ### Parameters -| Name | Type | Description | -| ------------- | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------- | -| **`query`** | `String` | The search query. As this value updates, the return value will be updated. | -| **`index`** | `Index \| String` | **Required**. The FlexSearch index. This can be an instance of a FlexSearch index or one that has been exported via `Index.export`. | -| **`store`** | `Object` | **Required**. Object mapping a result `id` to an object of data. | -| **`options`** | `Object` | Search options passed to `Index.search`. | +| Name | Type | Description | +| ------------- | ------------------ | ----------------------------------------------------------------------------------------------------------------------------------- | +| **`query`** | `String \| Object` | The search query. As this value updates, the return value will be updated. | +| **`index`** | `Index \| String` | **Required**. The FlexSearch index. This can be an instance of a FlexSearch index or one that has been exported via `Index.export`. | +| **`options`** | `Object` | Search options passed to `Index.search`. | ### Example @@ -40,21 +39,16 @@ Note: [Formik][formik] is used in the following example to handle form state, but is not required. As long as your query is passed as the first parameter, you can manage how to store it. -```js +```jsx import React, { useState } from 'react' import { useFlexSearch } from 'react-use-flexsearch' import { Formik, Form, Field } from 'formik' const index = /* a FlexSearch index */ -const store = { - 1: { id: 1, title: 'Document 1' }, - 2: { id: 2, title: 'Document 2' }, - 3: { id: 3, title: 'Document 3' }, -} const SearchBar = () => { const [query, setQuery] = useState(null) - const results = useFlexSearch(query, index, store) + const results = useFlexSearch(query, index) return ( {

Results

diff --git a/src/index.js b/src/index.js index c2e887f..a60824d 100644 --- a/src/index.js +++ b/src/index.js @@ -4,19 +4,13 @@ import FlexSearch from 'flexsearch' const InvalidIndexError = new Error( 'FlexSearch index is required. Check that your index exists and is valid.', ) -const InvalidStoreError = new Error( - 'FlexSearch store is required. Check that your store exists and is valid.', -) -export const useFlexSearch = (query, providedIndex, store, searchOptions) => { +export const useFlexSearch = (query, providedIndex, options) => { const [index, setIndex] = useState(null) useEffect(() => { if (!providedIndex) throw InvalidIndexError - if (!store) throw InvalidStoreError - }, [providedIndex, store]) - useEffect(() => { if (providedIndex instanceof FlexSearch) { setIndex(providedIndex) @@ -30,10 +24,8 @@ export const useFlexSearch = (query, providedIndex, store, searchOptions) => { }, [providedIndex]) return useMemo(() => { - if (!query || !index || !store) return [] - - const rawResults = index.search(query, searchOptions) + if (!query || !index) return [] - return rawResults.map(id => store[id]) - }, [query, index, store]) + return index.search(query, options) + }, [query, index]) } diff --git a/src/index.test.js b/src/index.test.js index 51e7c37..ab70ed9 100644 --- a/src/index.test.js +++ b/src/index.test.js @@ -30,12 +30,6 @@ documents.forEach(doc => { const exportedIndex = index.export() -const store = { - [documents[0].id]: documents[0], - [documents[1].id]: documents[1], - [documents[2].id]: documents[2], -} - beforeEach(() => { console.error = jest.fn() }) @@ -47,69 +41,55 @@ afterEach(() => { describe('useFlexSearch', () => { test('returns empty results if no query', () => { - let objResults - testHook(() => (objResults = useFlexSearch(null, index, store))) - - let exportedResults - testHook( - () => (exportedResults = useFlexSearch(null, exportedIndex, store)), - ) + let results + testHook(() => (results = useFlexSearch(null, index))) - expect(objResults).toEqual([]) - expect(exportedResults).toEqual([]) + expect(results).toEqual([]) }) test('returns empty results if query has no matches', () => { - let objResults - testHook(() => (objResults = useFlexSearch('nomatches', index, store))) + let results + testHook(() => (results = useFlexSearch('nomatches', index))) + + expect(results).toEqual([]) + }) + + test('returns results if query has matches', () => { + let results + testHook(() => (results = useFlexSearch(documents[0].name, index))) + + expect(results).toEqual([0]) + }) + + test('returns same results using instance and exported index', () => { + let instanceResults + testHook(() => (instanceResults = useFlexSearch(documents[0].name, index))) let exportedResults testHook( - () => - (exportedResults = useFlexSearch('nomatches', exportedIndex, store)), + () => (exportedResults = useFlexSearch(documents[0].name, exportedIndex)), ) - expect(objResults).toEqual([]) - expect(exportedResults).toEqual([]) + expect(instanceResults).toEqual([0]) + expect(instanceResults).toEqual(exportedResults) }) - test('returns results if query has matches', () => { - let objResults - testHook( - () => (objResults = useFlexSearch(documents[0].name, index, store)), - ) + test('returns results if query has matches using search options', () => { + let results + testHook(() => (results = useFlexSearch('JavaScript', index))) - let exportedResults + let limitedResults testHook( - () => - (exportedResults = useFlexSearch( - documents[0].name, - exportedIndex, - store, - )), + () => (limitedResults = useFlexSearch('JavaScript', index, { limit: 1 })), ) - expect(objResults).toEqual([documents[0]]) - expect(exportedResults).toEqual([documents[0]]) + expect(results).toEqual([1, 2]) + expect(limitedResults).toEqual([1]) }) test('throws if index is missing', () => { expect(() => { - testHook(() => useFlexSearch(documents[0].name, null, store)) - }).toThrow('index is required') - - expect(() => { - testHook(() => useFlexSearch(documents[0].name, undefined, store)) + testHook(() => useFlexSearch(documents[0].name)) }).toThrow('index is required') }) - - test('throws if store is missing', () => { - expect(() => { - testHook(() => useFlexSearch(documents[0].name, index, null)) - }).toThrow('store is required') - - expect(() => { - testHook(() => useFlexSearch(documents[0].name, index, undefined)) - }).toThrow('store is required') - }) })