#reactjs #firebase #google-cloud-firestore #react-redux
# #reactjs #firebase #google-облако-firestore #react-redux
Вопрос:
В настоящее время я пытаюсь загрузить данные о своем продукте в redux, но пока, похоже, я не могу передать информацию о продукте, возвращенную из firestore, в редуктор.
Index.js -> загрузите первые 10 товаров из firestore вскоре после создания магазина.
store.dispatch(getAllProducts)
action/index.js
import shop from '../api/shop'
const receiveProducts = products => ({
type: types.RECEIVE_PRODUCTS
products
})
const getAllProducts = () => dispatch => {
shop.getProducts(products => {
dispatch(receiveProducts)
})
}
shop.js
import fetchProducts from './firebase/fetchProducts'
export default {
getProducts: (cb) => cb(fetchProducts())
}
fetchProducts.js
const fetchProducts = async() => {
const ProductList = await firebase_product.firestore()
.collection('store_products').limit(10)
ProductList.get().then((querySnapshot) => {
const tempDoc = querySnapshot.docs.map((doc) => {
return { id: doc.id, ...doc.data() }
})
}).catch(function (error) {
console.log('Error getting Documents: ', error)
})
}
В редукторах продуктов
const byId = (state={}, action) => {
case RECEIVE_PRODUCTS:
console.log(action); <- this should be products, but it is now promise due to aysnc function return?
}
Я могу получить документы без проблем (tempDocs получает первые 10 документов без каких-либо проблем.), Но я не могу передать данные обратно в мой redux. Если бы я создавал обычное приложение react, я бы добавил состояние загрузки при получении документов из firestore, нужно ли мне делать что-то подобное и в redux?
Извините, если на данный момент код кажется беспорядочным.
Комментарии:
1. Я думаю, вам нужно взглянуть на redux-saga https://redux-saga.js.org /
Ответ №1:
fetchProducts
это асинхронная функция, поэтому вам нужно дождаться ее результата перед вызовом dispatch
. Есть несколько способов, которыми вы могли бы это сделать, вы могли бы предоставить fetchProducts
доступ dispatch
через перехват или передать отправку fetchProducts
напрямую.
Я не совсем понимаю цель shop.js
, но вы также можете await
fetchProducts
, а затем передать результат этого в отправку.
Комментарии:
1. Привет, спасибо за предложение. Итак, я предполагаю, что мне нужно создать промежуточное программное обеспечение для ожидания асинхронной функции? Что-то вроде этого redux.js.org/tutorials/fundamentals/part-6-async-logic
2. «Создать промежуточное программное обеспечение» звучит более формально, чем то, что я предлагаю. Все, что я говорю, это то, что отправка просто должна быть вызвана после получения результатов из firestore. И есть несколько разных мест, где я могу подумать о том, чтобы выполнить это ожидание, которое я предложил выше.
3. У меня это работает! Я не знал, что вы можете отправить результат напрямую. Ценю вашу помощь,
Ответ №2:
Обобщенная процедура, которую я использую для достижения именно этого:
const ListenGenerator = (sliceName, tableName, filterArray) => {
return () => {
//returns a listener function
try {
const unsubscribe = ListenCollectionGroupQuery(
tableName,
filterArray,
(listenResults) => {
store.dispatch(
genericReduxAction(sliceName, tableName, listenResults)
);
},
(err) => {
console.log(
err ` ListenGenerator listener ${sliceName} ${tableName} err`
);
}
);
//The unsubscribe function to be returned includes clearing
// Redux entry
const unsubscriber = () => {
//effectively a closure
unsubscribe();
store.dispatch(genericReduxAction(sliceName, tableName, null));
};
return unsubscriber;
} catch (err) {
console.log(
`failed:ListenGenerator ${sliceName} ${tableName} err: ${err}`
);
}
};
};
Он ListenCollectionGroupQuery
делает то, на что похоже; он принимает a tableName
, массив условий filter/.where() и обратные вызовы data/ err .
В genericReduxAction
значительной степени просто объединяет имя среза и имя таблицы для создания типа действия (мои редукторы аналогично деконструируют типы действий). Дело в том, что вы можете поместить отправку в обратный вызов данных.
Помимо этого, вы просто обрабатываете Redux как Redux — subscribe, get и т. Д., Как если бы данные были полностью локальными.