React一个项目的整体结构:目录和组件之间的分离

React一个项目的整体结构:目录和组件之间的分离

React 是一个库,它并不规定项目的整体结构。 这很棒,因为它让我们可以自由地尝试不同的方法并适应更适合我们的方法。 另一方面,这可能会给 React 世界的开发人员带来一些困惑。

在本文中,我将向您展示我已经使用了一段时间并且效果很好的方法。 这些方法不是通过重新发明轮子来实现的,而是通过社区中的解决方案进行组合和提炼。

想阅读更多优质文章,请戳GitHub博客,一年百篇优质文章等你来!

目录结构

我经常遇到的一个问题是如何组织文件和目录结构。 在本文中,我们假设您已经有了一个最小结构,例如使用 create-react-app 创建的结构。

create-react-app为我们生成了一个基础工程,包括根目录和.gitignore、package.json、README.md、yarn.lock等文件。

它还会生成 public 和 src 目录,src 目录是我们保存源代码的地方。

见下图,以及描述的结构:

clipboard.png

在本文中,我们只关注 src 目录,src 之外的一切保持不变。

容器和组件

您可能已经在某些项目的根部看到了容器组件和展示组件之间的分离。 我的意思是,在 src 中,src 目录下有 containers 目录和 components 目录:

src
├─ components 
└─ containers

但是,这种方法存在一些问题,如下:

还有另一种方法可以使容器和组件在模块内保持分离:

src
└─ User
  ├─ components
  └─ containers

上述方法最大限度地减少了项目树中不同级别目录之间的切换问题。 然而,它增加了很多噪音。 根据您的应用程序有多少个模块,您最终可能会创建数十个容器和组件目录。

由于这些原因,当我们谈论组织目录和文件时,通过显示容器的概念来拆分组件是无关紧要的。 即我们将除页面外的所有组件都放在components目录下。

尽管目录中没有必要区分展示组件和容器组件,但仍然有必要了解它们之间的区别。如果您对此主题仍有疑问,我建议阅读这篇文章:展示组件和容器组件拆分并结合代码

在组件目录中,我们按模块/功能对文件进行分组。

在用户的增删改查中游戏ui命名规范,我们只有User模块,结构是这样的

src
└─ components
  └─ User
    ├─ Form.jsx
    └─ List.jsx

当一个组件由多个文件组成时,我们将这个组件和它的文件放在一个同名的目录下。 例如:假设有一个Form.css,里面包含了Form.jsx的样式。 在这种情况下,您的结构如下:

src
└─ components
  └─ User
    ├─ Form
    │ ├─ Form.jsx
    │ └─ Form.css
    └─ List.jsx

测试文件与被测试文件保持一致。在上面的例子中,Form.jsx 测试文件将放在同一个文件夹中,并命名为 Form.spec.jsxUI 组件

除了按模块拆分组件外,我们还在 src/components 中包含一个 UI 目录,以将所有常用组件放在里面。

UI 组件是通用组件,而不是模块。 它们是可以保留在开源库中的组件,因为它们没有来自特定应用程序的任何业务逻辑。 这些组件的示例包括:按钮、输入、复选框、选择、模式、数据可视化组件等。

命名组件中的类

上面我们看到了如何构建目录并按模块分隔我们的组件。 但是,还有一个问题:如何命名它们?

当我们谈论命名组件时,它涉及到我们给类或定义组件的常量名称:

class MyComponent extends Component {
}
const MyComponent () => {};

如上所述,我们为组件命名的名称在应用程序中应该清晰且唯一,以便于查找并避免可能的混淆。

当我们需要使用像 React Dev 工具这样的工具进行调试时,组件的名称就派上用场了,当应用程序出现运行时错误时,错误总是带有发生错误的组件的名称。

我们采用基于路径的组件命名方式,即根据相对于组件文件目录的相对路径来命名。 如果它在此文件夹之外,请使用相对于 src 目录的路径。 例如,如果组件的路径是components/User/List.jsx,那么它将被命名为UserList。

当文件在具有相同名称的组件中时,我们不需要重复名称。 也就是说,components/User/Form/Form.jsx 将被命名为 UserForm 而不是 UserFormForm。

上面的模式有一些好处,我们可以在下面看到:

轻松搜索项目中的文件

如果编辑器支持模糊搜索,只需搜索名称UserForm即可找到正确的文件

clipboard.png

如果你想在目录中搜索文件,你可以很容易地通过组件名称找到它:

clipboard.png

导入时避免重名

按照这种模式,组件总是可以根据文件的上下文命名。 考虑到上面的表单,我们知道它是一个用户表单,但是因为我们已经在用户目录中,所以没有必要在组件文件名中重复这个词。 因此,我们将其命名为 Form.jsx。

刚开始使用 React 的时候,我喜欢用全名来命名文件游戏ui命名规范,但是这样会导致同一部分重复太多次,而且导入路径太长。 让我们看看这两种方法之间的区别:

import ScreensUserForm from './screens/User/UserForm';
// vs
import ScreensUserForm from './screens/User/Form';

在上面的示例中,可能无法看到从一种方法转到另一种方法的优势。 但是如果应用名太多的话,还是可以看出区别的,如下:

import MediaPlanViewChannel from '/MediaPlan/MediaPlanView/MediaPlanViewChannel.jsx';
// vs
import MediaPlanViewChannel from './MediaPlan/View/Channel';

想象一下重复这个名字十几次或二十次。

因此,我们根据上下文来命名文件,根据相对位置来命名组件是更好的方法。

页面(屏幕)

顾名思义,屏幕就是我们在应用程序中显示的内容。

如果我们要增加、删除、修改和查询一个用户,我们需要一个用户列表页面,一个创建新用户的页面,一个编辑现有用户的页面。

我们将屏幕保存在 src 根目录中的单独文件夹中,因为它们将按路由定义而不是模块分组:

src
├─ components 
└─ screens
  └─ User
    ├─ Form.jsx
    └─ List.jsx

考虑到项目使用了react-router,我们将文件Root.jsx放在screens目录下,并在里面定义了所有的应用路由。

Root.jsx 的代码可能如下所示:

import React, { Component } from 'react';
import { Router } from 'react-router';
import { Redirect, Route, Switch } from 'react-router-dom';
import ScreensUserForm from './User/Form';
import ScreensUserList from './User/List';
const ScreensRoot = () => (
  
    
      
      
      
    
  
);
export default ScreensRoot;

请注意,我们将所有页面放在以路由命名的目录中,user/ -> User/。 尝试为每个父路由创建一个目录,在这个目录中组织子路由。 在这种情况下,我们创建了 User 目录并将列表页面和表单页面放在其中。 这样就可以很方便的通过查看url定位到当前路由渲染的页面。

单个页面可用于呈现两个不同的路由,如上所述,以及用于创建和编辑用户的路由。

您可能会注意到所有组件的名称都以 Screen 作为前缀。 当组件位于components目录之外时,我们应该根据其相对于src文件夹的路径来命名。 位于 src/screens/User/List.jsx 中的组件应命名为 ScreensUserList。

创建好Root.jsx后,目录结构如下:

src
├─ components 
└─ screens
  ├─ User
  │ ├─ Form.jsx
  │ └─ List.jsx
  └─ Root.jsx

如果您仍然想知道页面是什么样子开发学习,请看下面的示例,这是一个用户表单页面。

import React from 'react';
import UserForm from '../../components/User/Form/Form';
const ScreensUserForm = ({ match: { params } }) => (
  

{`${!params.id ? 'Create' : 'Update'}`} User

); export default ScreensUserForm;

最终,我们的应用结构如下:

src
├─ components 
│  ├─ User
│  │ ├─ Form
│  │ │ ├─ Form.jsx
│  │ │ └─ Form.css
│  │ └─ List.jsx
│  └─ UI 
│
└─ screens
  ├─ User
  │ ├─ Form.jsx
  │ └─ List.jsx
  └─ Root.jsx

简要回顾

你的点赞是我继续分享好东西的动力橙光游戏,欢迎点赞!

欢迎加入前端大家庭,前端大家庭会经常分享一些技术资源。

clipboard.png