React新手求助:如何查询PouchDB并将文档信息存入Redux Store?
Hey there! Since you're working with the react-redux-pouchdb example project and already have remote sync set up, let's walk through exactly how to query your PouchDB documents and get that data into your Redux store. I'll share practical code examples tailored to your setup.
First, let's break this into three key steps: querying PouchDB, setting up Redux actions/reducers to handle the data, and fetching/using the data in your React components.
Step 1: Create Reusable PouchDB Query Functions
Start by adding functions to handle your database queries. You can drop these into your existing database setup file (like db.js in the example project):
import PouchDB from 'pouchdb'; // Assuming you already have these initialized from the example const localDb = new PouchDB('local-db'); const remoteDb = new PouchDB('your-remote-db-url'); // Example 1: Fetch ALL documents (includes full doc content) export const getAllDocuments = async () => { const result = await localDb.allDocs({ include_docs: true }); // Map the result to just the document data return result.rows.map(row => row.doc); }; // Example 2: Filter documents with a Mango query (e.g., by "type" property) export const getDocumentsByType = async (docType) => { const result = await localDb.find({ selector: { type: docType }, sort: [{ createdAt: 'desc' }] // Optional: sort by creation date }); return result.docs; };
Step 2: Set Up Redux Actions & Reducers
Next, create actions to trigger the queries and reducers to update your store with the results.
Redux Actions (e.g., src/actions/docActions.js)
import { getAllDocuments, getDocumentsByType } from '../db'; // Define action types export const FETCH_DOCS_SUCCESS = 'FETCH_DOCS_SUCCESS'; export const FETCH_DOCS_ERROR = 'FETCH_DOCS_ERROR'; // Async action to fetch all documents export const fetchDocuments = () => async (dispatch) => { try { const docs = await getAllDocuments(); dispatch({ type: FETCH_DOCS_SUCCESS, payload: docs }); } catch (error) { dispatch({ type: FETCH_DOCS_ERROR, payload: error.message }); } }; // Async action to fetch filtered documents (by type) export const filterDocumentsByType = (docType) => async (dispatch) => { try { const docs = await getDocumentsByType(docType); dispatch({ type: FETCH_DOCS_SUCCESS, payload: docs }); } catch (error) { dispatch({ type: FETCH_DOCS_ERROR, payload: error.message }); } };
Redux Reducer (e.g., src/reducers/docReducer.js)
import { FETCH_DOCS_SUCCESS, FETCH_DOCS_ERROR } from '../actions/docActions'; // Initial state for your documents slice const initialState = { documents: [], error: null }; export const docReducer = (state = initialState, action) => { switch (action.type) { case FETCH_DOCS_SUCCESS: return { ...state, documents: action.payload, error: null }; case FETCH_DOCS_ERROR: return { ...state, error: action.payload }; default: return state; } };
Don't forget to add this reducer to your root reducer (merge it with the example project's existing reducers):
// src/reducers/index.js import { combineReducers } from 'redux'; import { docReducer } from './docReducer'; // Import other reducers from the example project here (e.g., auth, sync) export const rootReducer = combineReducers({ docs: docReducer, // Add existing reducers from the example here });
Step 3: Fetch & Display Data in a React Component
Now you can use Redux hooks to fetch the data and render it in your component:
import React, { useEffect } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { fetchDocuments } from '../actions/docActions'; const DocumentList = () => { const dispatch = useDispatch(); // Pull data from the Redux store const { documents, error } = useSelector(state => state.docs); // Fetch documents when the component mounts useEffect(() => { dispatch(fetchDocuments()); }, [dispatch]); // Handle error state if (error) { return <div>Oops! Error loading documents: {error}</div>; } return ( <div className="document-list"> <h2>My Synced Documents</h2> {documents.length === 0 ? ( <p>No documents found.</p> ) : ( <ul> {documents.map(doc => ( <li key={doc._id}> <h3>{doc.title || 'Untitled Document'}</h3> <p>{doc.content}</p> </li> ))} </ul> )} </div> ); }; export default DocumentList;
Bonus: Auto-Update Store When Sync Occurs
If you want your Redux store to automatically update whenever the remote sync changes documents, add a PouchDB change listener to your db.js file:
// In db.js import store from '../store'; // Import your Redux store import { FETCH_DOCS_SUCCESS } from '../actions/docActions'; import { getAllDocuments } from './db'; // Listen for live changes to the local DB (triggered by sync) localDb.changes({ since: 'now', live: true, include_docs: true }).on('change', async () => { // Refresh the document list in the store const updatedDocs = await getAllDocuments(); store.dispatch({ type: FETCH_DOCS_SUCCESS, payload: updatedDocs }); }).on('error', (err) => { console.error('Error listening for DB changes:', err); });
This way, any sync updates will automatically reflect in your Redux store and UI without needing to manually refetch.
内容的提问来源于stack exchange,提问作者bumblebee

