我正在与我的团队一起建立一个React项目,该项目将使用mobX作为状态管理器以及TypeScript。
我已经在React Projects的大小写和命名模式中看到了一个常见的模式:
camelCase
kebab-case
components
PascalCase
在react中是否有文件夹/文件命名的正式约定?如果不是,是否有该样式所基于的样式指南?还是大多数情况下都使用此原因的原因?
只是加上我的两分钱。正如其他人所说,文件结构是不受限制的。但是,组件命名不是。他们 应该 是PascalCase为应对知道你是否正在使用function,class或HTMLelement†。
function
class
HTMLelement
例如:
class input extends Component {...}
不好 !为什么?因为React不知道您是要使用input元素还是基于类的组件。
input
这就是为什么您会看到PascalCase组件的原因:
class Input extends Component {...}
†有一个例外,您可以在其中使用dot notation。例如,如果您有多个导出并将它们全部导入为fields,则可以执行以下操作:
dot notation
fields
组件/字段/ index.js
import React, { Component } from 'react'; export class input extends Component { state = { value: "" }; handleChange = ({ target: { value } }) => { this.setState({ value }); }; render = () => ( <input type="text" value={this.state.value} onChange={this.handleChange} /> ); } export class textarea extends Component { state = { value: "" }; handleChange = ({ target: { value } }) => { this.setState({ value }); }; render = () => ( <textarea type="text" value={this.state.value} onChange={this.handleChange} /> ); }
组件/App/index.js
import React, { Fragment } from 'react'; import * as fields from "../fields"; const App = () => ( <Fragment> <fields.input /> <fields.textarea /> <Fragment> ); export default App;
一般而言,我dot notation完全避免使用。感觉笨拙,可能会使其他不了解fields其结构的开发人员感到困惑。另外,我不喜欢在一个文件中堆叠多个组件,然后将它们作为一堆导入。此外,该文件可能会变得很大且导航和调试很麻烦(有关此内容,请参见下文)。
就是说,为了保持结构简单,我喜欢将主目录保持小写:
├── dist // compiled application files to be served | ├── css | | ├── main.[contenthash:8].css | | └── main.[contenthash:8].css.map | ├── js | | ├── main.[hash].js // depending on app size, this may contain multiple js files for code splitting | | └── main.[hash].js.map | ├── media | | └── [hash].[ext] // static assets like fonts and images | └── favicon.ico | └── index.html | ├── config // supporting "webpackdevserver" configuration files | ├── devServer.js | ├── envs.js | ├── optimization.js | ├── output.js | ├── paths.js | ├── plugins.js | └── rules.js | ├── public | ├── favicon.ico | └── index.html | ├── src | ├── actions // redux actions | ├── components // stateful and stateless reusable components that just display "stuff" -- stateful components change and manipulate the UI | ├── containers // stateful components that utilize the reusable "components" to CRUD data and/or are connected to redux | ├── images | ├── pages // utilize components/containers to display something when visiting a "/route" | ├── reducers // redux reducers | ├── root // aka "<App />" that combines "routes", redux and other top-level supporting files into one place | ├── routes // assigns "pages" to a "/route" | ├── styles // shared and/or global styles used by all "components" | ├── types // redux types | ├── utils // supporting app files: like test setup, custom polyfills, axios configurations, ...etc | └── index.js // a simple file that "ReactDOM.render"s the "App" | ├── server.js // express setup to serve the "dist" folder └── webpack.config.js
然后在该component文件夹中,我将PascalCase我的组件代表这样的东西:
component
└── components └── Input ├── __tests__ | └── Input.test.js // jest unit tests for "index.js" ├── index.js // all required code/styles to be exported └── styles.scss // styles required by "index.js"
为什么是这种结构?
Input
index.js
import Input from 'components/Input';
js
缺点:
我曾经做过的另一种方法是:
└── components ├── input // lowercase name to delineate it's a "pure" function -- the actual function will be a PascalCased "Input" | ├── input.test.js // jest unit tests for "input.js" | ├── input.js // all required code/styles to be exported | └── styles.scss // styles required by "input.js" | └── Sidebar // PascalCase because it's a "class" ├── Sidebar.test.js // jest unit tests for "Sidebar.js" ├── Sidebar.js // all required code/styles to be exported └── styles.scss // styles required by "Sidebar.js"
import Input from 'components/input/input.js';
其他一般准则:
默认导出的匿名函数的示例:
export default () => ( <p>Anonymous Function</p> );
为什么?因为在测试时,该功能将在酶中显示为:
<_default />
当一个组件中有多个匿名函数时,哪个是哪个!
<_default /> <_default /> <_default />
我发现, 通常情况 下,如果适当地进行优化, 大多数 组件将在100行以下。最坏的情况是我将不得不创建小的子组件来补充主组件。但!更容易阅读和调试。
什么更容易阅读:
Example#1(34行带有辅助子组件)
Example#2(所有318行)
示例1模仿读书。粘贴在一起的多个页面可提供易于阅读的体验。与示例2相对,该示例读取的内容像一英里长的滚动条,很容易迷路!
这可能会造成混淆,但是这完全取决于您如何应用样式。如果您只是这样导入样式:
import "./styles.css";
然后,您可以使用蛇形保护套:
<input className="snake-case" type="text" value="" onChange={this.handleChange} />
但是,如果您使用css modules,则需要使用camelCase:
css modules
import { camelCaseClassName } from "./styles.css";
为什么?因为捆绑器(如Webpack)不支持蛇形导入:
<input className={camelCaseClassName} type="text" value="" onChange={this.handleChange} />
结论:创建文件夹结构的方法有很多种,其中有一些提示和技巧来保持逻辑流程。只要选择一个最适合您并且不会干扰在您旁边工作的人!
换句话说,KISS ===“保持简单,愚蠢!”