我应该将用于将新数据写入 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

...例如,从 actionsreducerbusiness.

导入然后导出所有 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

的底层结构发生变化

正如我所说,完全我的特质,但它有助于分离责任。