Как я могу интегрировать React-Redux с Firebase?

#reactjs #firebase #redux

#reactjs #firebase #redux

Вопрос:

Я создал приложение react с использованием create-react-app и настроил хранилище redux с редукторами. Я также добавил firebase, и мой проект работает нормально. Компоненты могут запускать действие, которое извлекает коллекцию из firestore, а оно, в свою очередь, обновляет хранилище redux.

Каков наилучший способ интеграции firebase и redux store? То, как я сейчас это делаю, заключается в том, чтобы иметь отдельное действие, которое запускает выборку / удаление / onSnapshot из firebase, и передает ссылку dispatch , чтобы функция firebase могла не торопиться с выполнением команды, затем она может вызвать dispatch с действием, которое обновляет хранилище.

Но я хотел, чтобы все мои действия были в одном файле, для лучшего (разделения проблем). Поэтому firebase может вызывать отправку, но создатель действия живет в моем actions.js досье. Таким образом, я могу позже решить изменить имена действий в одном файле, если я решу это сделать.

Проблема с этим подходом заключается в том, что мне потребуется отдельное действие для запуска асинхронной функции с firebase и другого создателя действия для выполнения обещания.

Какой лучший подход к тому, что я делаю?

store.js

 const rootReducer = combineReducers({
    cards: cardsReducer,
});

const store = createStore( rootReducer , {}, applyMiddleware(thunk));
export default store;
 

myFirebase.js

 // I need this to be called from an action in actions.js
// therefor, I am exporting it, and also, I am handing it dispatch
// so it will call store.dispatch once data is ready

export const fetchCardsFromFirebase = async (dispatch) => {
    const cardsCollection = collection(db, "cards");
    const cardsSnapshot = await getDocs(roomsCollection);
    const cards = roomsSnapshot.docs.map(doc => ({ ...doc.data(), id: doc.id }));
    // here I can either explicitly dispatch an action 
    /*
    dispatch({
       type: CARDS_FETCHED         //this constant string will have to be imported
       payload: cards
    });
    */

    // or I can let an action in actions.js do the above:
    dispatch(cardsFetched(rooms));   //this function is imported from actions.js
}
 

actions.js

 import { FETCH_CARDS , CARDS_FETCHED } from "./types";
import { fetchCardsFromFirebase } from "../myFirebase";

export const fetchCards = () => async (dispatch) => {

    fetchCardsFromFirebase(dispatch);  // give firebase access to dispatch

    dispatch({
        type: FETCH_CARDS,
        payload: {message: "fetching cards... please wait"}
    });
};

const cardsFetched = (cards) => ({
   action: CARDS_FETCHED,
   payload: cards
});
 

Ответ №1:

Как правило, это очень старый стиль Redux — современный Redux не использует редукторы switch ..case или ACTION_TYPES, и переход на современный Redux, вероятно, уже сэкономит вам 50% вашего кода.

Тем не менее, официальный инструментарий Redux Toolkit (RTK) также поставляется с RTK-Query, который представляет собой абстракцию кэширования данных, которая также должна хорошо работать с firebase и автоматически генерировать для вас редукторы, действия и даже перехваты. (Подсказка: с firebase вам нужно будет использовать queryFn ). Это также сэкономит вам намного больше кода.

Я бы рекомендовал вам следовать официальному руководству по Redux, в котором сначала показан современный Redux, а в последующих главах рассматривается RTK-запрос.