TypeScript环境下Firestore Reducer代码相关技术咨询
Hey there! Let's walk through your reducer code and cover key points, common pitfalls, and improvements to make sure this setup works smoothly for your app.
First, let's confirm what your code does: you're combining three core reducers—firebaseReducer (for React Redux Firebase state), firestoreReducer (for Redux Firestore state), and routerReducer (for React Router state)—into a single root reducer, with TypeScript type safety for your ApplicationState. Great start following the tutorial!
1. Fix Type Safety for ApplicationState
If you haven't already defined the ApplicationState interface, you'll run into TypeScript errors. Instead of manually typing each state slice, use ReturnType to auto-infer the reducer's output type—this keeps your types in sync as reducers update:
// Define your app's root state type interface ApplicationState { firebase: ReturnType<typeof firebaseReducer>; firestore: ReturnType<typeof firestoreReducer>; router: ReturnType<typeof routerReducer>; }
2. Critical Middleware & Initialization (Don't Skip This!)
Your reducer setup alone won't work—you need to configure the corresponding middleware and initialize Firebase/Firestore to sync state with your backend. This is the most common mistake for beginners following these tutorials.
Here's a complete store setup example to pair with your reducers:
import { createStore, applyMiddleware, compose } from 'redux'; import thunk from 'redux-thunk'; import { reactReduxFirebase, getFirebase } from 'react-redux-firebase'; import { reduxFirestore, getFirestore } from 'redux-firestore'; import firebase from 'firebase/app'; import 'firebase/firestore'; import 'firebase/auth'; import { reducers } from './your-reducer-file-path'; // Your Firebase project config (from Firebase Console) const firebaseConfig = { apiKey: "YOUR_API_KEY", authDomain: "YOUR_AUTH_DOMAIN", projectId: "YOUR_PROJECT_ID", storageBucket: "YOUR_STORAGE_BUCKET", messagingSenderId: "YOUR_SENDER_ID", appId: "YOUR_APP_ID" }; // Initialize Firebase firebase.initializeApp(firebaseConfig); // React Redux Firebase config (customize based on your needs) const rrfConfig = { userProfile: 'users', // Sync user profiles to Firestore's "users" collection useFirestoreForProfile: true // Use Firestore instead of Realtime DB for profiles }; // Create store with middleware and enhancers const store = createStore( reducers, compose( // Add thunk middleware to access Firebase/Firestore in async actions applyMiddleware(thunk.withExtraArgument({ getFirebase, getFirestore })), // Sync Firebase state to Redux reactReduxFirebase(firebase, rrfConfig), // Sync Firestore state to Redux reduxFirestore(firebase), // Enable Redux DevTools for debugging (only in development) process.env.NODE_ENV === 'development' ? window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__() : (f) => f ) ); export default store;
3. Version Compatibility Checks
Make sure your dependency versions play nicely together:
react-router-reduxis deprecated for React Router v4+. If you're using React Router v4 or later, switch toconnected-react-routerfor router state sync (itsrouterReducerworks the same way but is actively maintained).- Confirm
react-redux-firebaseandredux-firestoreversions match your React (^16.8.0+for hooks support) and Redux (^4.0.0+) versions.
4. Migrate to Redux Toolkit (Modern, Cleaner Approach)
If you're not already using Redux Toolkit, it's the official recommended way to write Redux code—it simplifies setup, reduces boilerplate, and includes built-in best practices. Here's how to adapt your code:
import { configureStore } from '@reduxjs/toolkit'; import thunk from 'redux-thunk'; import { reactReduxFirebase } from 'react-redux-firebase'; import { reduxFirestore } from 'redux-firestore'; import firebase from 'firebase/app'; import { reducers } from './your-reducer-file-path'; import { rrfConfig } from './your-firebase-config'; const store = configureStore({ reducer: reducers, middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat( thunk.withExtraArgument({ getFirebase, getFirestore }) ), enhancers: (defaultEnhancers) => [ ...defaultEnhancers, reactReduxFirebase(firebase, rrfConfig), reduxFirestore(firebase) ] }); export default store;
5. Debugging Tips
- Redux DevTools: Always enable them in development to inspect the
firebase,firestore, androuterstate slices—this helps you confirm if state is syncing correctly. - Router Sync: If your router state isn't updating, ensure you're using
ConnectedRouter(fromreact-router-reduxorconnected-react-router) to wrap your app, and pass the store to it. - Firebase Errors: Check your browser console for Firebase initialization errors or permission issues—these often cause state sync failures that aren't obvious from the reducer alone.
If you're hitting a specific error (like TypeScript type issues, state not updating, or middleware conflicts), share the details and we can dive deeper!
内容的提问来源于stack exchange,提问作者Evaldas Buinauskas

