useFind
Overview
Query, and optionally create, a Mango query. It uses the Mango query language.
It also subscripts to updates of the index. With the added bonus of also subscribing to updates of
the documents in the result. If you update or delete a document in a way that would
remove it from the index, than it will be removed from the result of this hook. Even if _id
is
not included in fields
.
The hook is a combination of db.createIndex()
and db.find()
. With the right arguments (options.index
),
it will ensure that an index exist, using db.createIndex()
, and use that index with db.find()
.
useFind
can only be invoked from a component nested inside of a <Provider />
.
useFind
requirespouchdb-find
to be installed and setup.
Parameters
useFind
has a combination of PouchDB's db.find()
and db.createIndex()
options.
Options descriptions are copied from the PouchDB API page.
options: object
- Option object.options.index?: string | [string, string] | CreateIndexOption
- Select an index or ensure an index exist. It can be:string
- Select the design-doc to be used. It is likedb.find()
'suse_index
.[string, string]
- Select the design-doc and index name. It is likedb.find()
'suse_index
.object
- Ensure that this index exist, create it if not. The hook will then use that index. It is theindex
field, passed intodb.createIndex()
.options.index.fields: string[]
- A list of fields to index. The order matters!options.index.name?: string
- Name of the index, auto-generated if not included.options.index.ddoc?: string
- design document name (i.e. the part after'_design/'
), auto-generated if you don’t include itoptions.index.type?: string
- Type of the index. Onlyjson
is supported, which is also the default.options.index.partial_filter_selector?: PouchDB.Find.Selector
- A selector used to filter the set of documents included in the index. Read more in the CouchDB docs.
options.selector: PouchDB.Find.Selector
- The selector to filter the results. Required. It uses Mango Selector Syntax.options.fields?: string[]
- List of fields that you want to receive. If omitted, you get the full documents.options.sort?: string[]
- List of fields defining how you want to sort. Note that sorted fields also have to be selected in theoptions.selector
.options.limit?: number
- Maximum number of documents to return.options.skip?: number
- Number of docs to skip before returning.options.db?: string
- Selects the database to be used. The database is selected by it's name/key. The special key"_default"
selects the default database. Defaults to"_default"
.
index
,selector
,fields
andsort
are check for equality with a deep equal algorithm. And only if they differentiate by value will they cause a new query to be made.
Note:
useFind
will calldb.createIndex
every time theindex
object's values changed! It will happily create a new index on every render!
Result
useFind
results an object with those fields:
docs: object[]
- Array of objects that contain the requested documents. Empty during the first fetch or during an error. Each object has only the requested fields, or the full document if nofields
array was defined.warning?: string
- Ifdb.find()
returns a warning, it will be included here. For example if no matching index was found. Create an index in theoptions.index
field if no index was found.state: 'loading' | 'done' | 'error'
- Current state of the hook.loading
- It is loading the documents. Or it is loading the updated version of them.done
- The documents are loaded, and no update is being loaded.error
- There was an error with fetching the documents. Look into theerror
field.
loading: boolean
- It is loading. The state isloading
. This is only a shorthand.error: PouchDB.Error | null
- If there was an error, then this field will contain the error. The error is reset tonull
once a fetch was successful.
Example Usage
Ensure that an index exist
If the index field contains an object with a fields-field, useFind will ensure that that index exist. If the index doesn't exist, it will be created.
This is the recommended usage.
import React from 'react'
import { useFind } from 'use-pouchdb'
export default function StoryList() {
const { docs, loading, error } = useFind({
// Ensure that this index exist, create it if not. And use it.
index: {
fields: ['type', 'title'],
// 'ddoc' and 'name' are not required. PouchDB will check all existing indexes
// if they match the requirements. And only create a one if none match.
},
selector: {
type: 'story',
title: { $exists: true },
},
sort: ['title'],
fields: ['_id', 'title'],
})
return (
<main>
<h1>Stories</h1>
{error && (
<p>
Error: {error.status} - {error.name}
</p>
)}
{loading && docs.length === 0 && <p>loading...</p>}
<ul>
{docs.map(doc => (
<li key={doc._id}>
<a href={`./${doc._id}`}>{doc.title}</a>
</li>
))}
</ul>
</main>
)
}
Use existing index
import React from 'react'
import { useFind } from 'use-pouchdb'
export default function StoryList() {
const { docs, loading, error } = useFind({
// index is here like use_index in db.find()
index: ['ddoc_name', 'index_name'],
selector: {
type: 'story',
title: { $exists: true },
},
sort: ['title'],
fields: ['_id', 'title'],
})
return (
<main>
<h1>Stories</h1>
{error && (
<p>
Error: {error.status} - {error.name}
</p>
)}
{loading && docs.length === 0 && <p>loading...</p>}
<ul>
{docs.map(doc => (
<li key={doc._id}>
<a href={`./${doc._id}`}>{doc.title}</a>
</li>
))}
</ul>
</main>
)
}
Select a database
import React from 'react'
import { useFind } from 'use-pouchdb'
export default function StoryList({ isLocalReady }) {
const { docs, loading, error } = useFind({
// index is here like use_index in db.find()
index: ['ddoc_name', 'index_name'],
selector: {
type: 'story',
title: { $exists: true },
},
sort: ['title'],
fields: ['_id', 'title'],
// Select the database used
db: isLocalReady ? 'local' : 'remote',
})
return (
<main>
<h1>Stories</h1>
{error && (
<p>
Error: {error.status} - {error.name}
</p>
)}
{loading && docs.length === 0 && <p>loading...</p>}
<ul>
{docs.map(doc => (
<li key={doc._id}>
<a href={`./${doc._id}`}>{doc.title}</a>
</li>
))}
</ul>
</main>
)
}