我应该将用于将新数据写入 Firestore 的逻辑放在哪里?
Where should I put my logic for writing new data to Firestore?
我目前正在使用 React 和 Firebase 开发一个项目,目前我将新数据写入 Firestore 的逻辑直接在我的组件中。我现在也在集成 Redux,为此我正在使用 react-redux-firebase。我现在的问题是,放置此逻辑的最佳位置在哪里,因为它使我的组件安静臃肿。
在react-redux-firebase的documentation中,他们也直接放在了组件中,但是他们的逻辑很简单,我的有点复杂,像这样handleSubmit:
const handleSubmit = async (e) => {
e.preventDefault();
setDisabled(true); //disable button to prevent multiple sbumits
setLoading(true);
try {
const docRef = await firestore.collection("goodies").add(newGoodieData); // create new event
await firestore.collection("goodies").doc(docRef.id).update({
// add eventId to event doc
id: docRef.id,
});
if (image) {
const imageName = docRef.id + "." + image.name.split(".").pop(); //create image name with eventID and file extions
const imageRef = storage.ref().child("goodie_images/").child(imageName); //create imageRef
const imageSnapshot = await imageRef.put(image); //upload image to storage
const downloadUrl = await imageSnapshot.ref.getDownloadURL(); //get image download-url
const imagePath = imageRef.fullPath; // get image storage path
await firestore.collection("goodies").doc(docRef.id).update({
//update event with imageUrl and imagePath
image: downloadUrl,
imagePath: imagePath,
});
}
setDisabled(false);
setLoading(false);
dispatch(showSuccessToast(`Created new goodie "${newGoodieData.name}"!`));
history.push("/goodies");
} catch (error) {
dispatch(showErrorToast("Ops, an error occurred!"));
console.error(error.message);
}
};
这完全是我的怪癖,但我使用了如下结构。一般情况下,组件和页面(即react组件)名称首字母大写:
src
|-blocks
|-components
|-css
|-navigation
|-pages
|-services
|-App.js
|-constants.js
|-index.js
块
这些是我的特定于应用程序的组件,以及一些更大的特定于应用程序的功能。
|-blocks
|-Block1
| |-index.js
| |-aSubModule.js
|-Block2
| |-index.js
| |-aSubModule.js
etc, etc
组件
这些是“通用”组件 - 即 可以 作为模块发布,或者从外部模块定制。这些不是特定于应用程序的。类似于“块”的结构
|-components
|-ComponentThatDoesThisThing
|-ComponentThatDoesThatThing
etc, etc
CSS
顾名思义...
导航
页眉、页脚、导航菜单。还有导航辅助功能(例如包装页面链接等)
|-navigation
|-Header
|-Menu
|-Footer
etc, etc
页数
我所有的反应页面和子页面,无论深度如何。页面下面的所有内容都是特定于应用程序的
|-pages
|-Users
| |-Home
| | |index.js
| | |-etc,etc
| |-Account
| |-Bio
| |-etc,etc
|-Owners
| |-Home
| |-Account
| |-Bio
| |-etc,etc
|-index.js
以及更直接地解决您的问题的地方:
服务
|-services
|-reduxEnhancers
|-reduxMiddleware
|-reduxRootReducers
|-slices
|-configureStore.js
|-firestore.js
与教程没有太大区别。但这就是我的切片中的内容 - 或多或少对应于 redux 状态切片:
切片
|-services
|-slices
|-UserSlice
| |-actions
| | |-index.js
| |-reducer
| | |-index.js
| |-business
| | |-index.js
| |-index.js
|-OwnerSlice
| |-actions
| | |-index.js
| |-reducer
| | |-index.js
| |-business
| | |-index.js
| |-index.js
|-KitchCupboardSlice
| |-actions
| | |-index.js
| |-reducer
| | |-index.js
| |-business
| | |-index.js
| |-index.js
|-etc,etc slices
|-index.js
重要说明:大多数 Redux 教程显示 Redux 切片具有与 React 组件相同的分支结构。总的来说,这并不是所有的情况,我还没有找到它甚至有帮助的情况。你的数据的树状结构不一定像你的页面和反应组件的树状结构 - 按照 data 想要你的方式划分你的 Redux 存储,而不是面向用户的 React 希望您这样做的方式。对于本论坛而言,更重要的是:让数据的 FIRESTORE 结构为您提供指导。
正在使用:
|-services
|-slices
|-UserSlice
|-index.js
...例如,从 actions
、reducer
和 business
.
导入然后导出所有 public/exported 符号
|-services
|-slices
|-UserSlice
|-reducer
...reducer
使用 store.injectReducer 将自己添加到 Redux 存储中,使用
中定义的符号和常量
|-services
|-slices
|-UserSlice
|-actions
...actions
,它还创建了特定的 Redux 操作和辅助样板(操作、选择器等)。
有助于分工负责:
|-services
|-slices
|-UserSlice
|-business
...business
子目录包含您提到的业务逻辑 - React 组件可能需要调用的任何逻辑,这些逻辑不是 React 模块的显示和状态方面的特定本地逻辑。这也是我定义对 firestore 或任何其他外部服务或获取的任何访问的地方——React 组件不应该关心这是如何完成的。
为了更方便地访问所有这些不同的出口,我使用
|-services
|-slices
|-index
...从所有切片导入然后导出所有 public/exported 符号。可以更轻松地导入各种 React 组件,而不必担心 slices
的底层结构发生变化
正如我所说,完全我的特质,但它有助于分离责任。
我目前正在使用 React 和 Firebase 开发一个项目,目前我将新数据写入 Firestore 的逻辑直接在我的组件中。我现在也在集成 Redux,为此我正在使用 react-redux-firebase。我现在的问题是,放置此逻辑的最佳位置在哪里,因为它使我的组件安静臃肿。
在react-redux-firebase的documentation中,他们也直接放在了组件中,但是他们的逻辑很简单,我的有点复杂,像这样handleSubmit:
const handleSubmit = async (e) => {
e.preventDefault();
setDisabled(true); //disable button to prevent multiple sbumits
setLoading(true);
try {
const docRef = await firestore.collection("goodies").add(newGoodieData); // create new event
await firestore.collection("goodies").doc(docRef.id).update({
// add eventId to event doc
id: docRef.id,
});
if (image) {
const imageName = docRef.id + "." + image.name.split(".").pop(); //create image name with eventID and file extions
const imageRef = storage.ref().child("goodie_images/").child(imageName); //create imageRef
const imageSnapshot = await imageRef.put(image); //upload image to storage
const downloadUrl = await imageSnapshot.ref.getDownloadURL(); //get image download-url
const imagePath = imageRef.fullPath; // get image storage path
await firestore.collection("goodies").doc(docRef.id).update({
//update event with imageUrl and imagePath
image: downloadUrl,
imagePath: imagePath,
});
}
setDisabled(false);
setLoading(false);
dispatch(showSuccessToast(`Created new goodie "${newGoodieData.name}"!`));
history.push("/goodies");
} catch (error) {
dispatch(showErrorToast("Ops, an error occurred!"));
console.error(error.message);
}
};
这完全是我的怪癖,但我使用了如下结构。一般情况下,组件和页面(即react组件)名称首字母大写:
src
|-blocks
|-components
|-css
|-navigation
|-pages
|-services
|-App.js
|-constants.js
|-index.js
块
这些是我的特定于应用程序的组件,以及一些更大的特定于应用程序的功能。
|-blocks
|-Block1
| |-index.js
| |-aSubModule.js
|-Block2
| |-index.js
| |-aSubModule.js
etc, etc
组件
这些是“通用”组件 - 即 可以 作为模块发布,或者从外部模块定制。这些不是特定于应用程序的。类似于“块”的结构
|-components
|-ComponentThatDoesThisThing
|-ComponentThatDoesThatThing
etc, etc
CSS
顾名思义...
导航
页眉、页脚、导航菜单。还有导航辅助功能(例如包装页面链接等)
|-navigation
|-Header
|-Menu
|-Footer
etc, etc
页数
我所有的反应页面和子页面,无论深度如何。页面下面的所有内容都是特定于应用程序的
|-pages
|-Users
| |-Home
| | |index.js
| | |-etc,etc
| |-Account
| |-Bio
| |-etc,etc
|-Owners
| |-Home
| |-Account
| |-Bio
| |-etc,etc
|-index.js
以及更直接地解决您的问题的地方:
服务
|-services
|-reduxEnhancers
|-reduxMiddleware
|-reduxRootReducers
|-slices
|-configureStore.js
|-firestore.js
与教程没有太大区别。但这就是我的切片中的内容 - 或多或少对应于 redux 状态切片:
切片
|-services
|-slices
|-UserSlice
| |-actions
| | |-index.js
| |-reducer
| | |-index.js
| |-business
| | |-index.js
| |-index.js
|-OwnerSlice
| |-actions
| | |-index.js
| |-reducer
| | |-index.js
| |-business
| | |-index.js
| |-index.js
|-KitchCupboardSlice
| |-actions
| | |-index.js
| |-reducer
| | |-index.js
| |-business
| | |-index.js
| |-index.js
|-etc,etc slices
|-index.js
重要说明:大多数 Redux 教程显示 Redux 切片具有与 React 组件相同的分支结构。总的来说,这并不是所有的情况,我还没有找到它甚至有帮助的情况。你的数据的树状结构不一定像你的页面和反应组件的树状结构 - 按照 data 想要你的方式划分你的 Redux 存储,而不是面向用户的 React 希望您这样做的方式。对于本论坛而言,更重要的是:让数据的 FIRESTORE 结构为您提供指导。
正在使用:
|-services
|-slices
|-UserSlice
|-index.js
...例如,从 actions
、reducer
和 business
.
|-services
|-slices
|-UserSlice
|-reducer
...reducer
使用 store.injectReducer 将自己添加到 Redux 存储中,使用
|-services
|-slices
|-UserSlice
|-actions
...actions
,它还创建了特定的 Redux 操作和辅助样板(操作、选择器等)。
有助于分工负责:
|-services
|-slices
|-UserSlice
|-business
...business
子目录包含您提到的业务逻辑 - React 组件可能需要调用的任何逻辑,这些逻辑不是 React 模块的显示和状态方面的特定本地逻辑。这也是我定义对 firestore 或任何其他外部服务或获取的任何访问的地方——React 组件不应该关心这是如何完成的。
为了更方便地访问所有这些不同的出口,我使用
|-services
|-slices
|-index
...从所有切片导入然后导出所有 public/exported 符号。可以更轻松地导入各种 React 组件,而不必担心 slices
正如我所说,完全我的特质,但它有助于分离责任。