关于react.js:react-开发规范

43次阅读

共计 4436 个字符,预计需要花费 12 分钟才能阅读完成。

1. 根本规定

• 一个文件申明一个组件:只管能够在一个文件中申明多个 React 组件,然而最好不要这样做;举荐一个文件申明一个 React 组件,并只导出一个组件;

• 应用 JSX 表达式:不要应用 React.createElement 的写法;

• react 18 尽量应用函数组件。

2. 命名标准

扩展名 : 用 .tsx 作为组件扩展名。

文件名 : 用大驼峰作为文件名,如:ReservationCard.tsx

参数命名 : React 组件用大驼峰,组件的实例用小驼峰。eslint: [react/jsx-pascal-case](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-pascal-case.md)

// bad
import reservationCard from './ReservationCard';

// good
import ReservationCard from './ReservationCard';

// bad
const ReservationItem = <ReservationCard />;

// good
const reservationItem = <ReservationCard />;

组件命名 : 文件名作为组件名。例如:ReservationCard.jsx 应该用 ReservationCard 作为参数名。然而,对于一个文件夹里的跟组件,应该用 index.jsx 作为文件名,同时用文件夹名作为组件名

// bad
import Footer from './Footer/Footer';

// bad
import Footer from './Footer/index';

// good
import Footer from './Footer';

高阶组件 HOC 命名 : 用高阶组件名和传入的组件名组合作为生成的组件的 displayName。举个例子,一个高阶组件 withFoo(),当传入一个组件 Bar 应该生成一个新的组件,他的 displayName 属性是 withFoo(Bar)。

Why? 组件的 displayName 能够用于开发者工具或者错误信息中,同时还有一个值能够清晰的表白这种组件关系,这能够帮忙人们了解到底产生了什么

// bad
export default function withFoo(WrappedComponent) {return function WithFoo(props) {return <WrappedComponent {...props} foo />;
  }
}

// good
export default function withFoo(WrappedComponent) {function WithFoo(props) {return <WrappedComponent {...props} foo />;
  }

  const wrappedComponentName = WrappedComponent.displayName
    || WrappedComponent.name
    || 'Component';

  WithFoo.displayName = `withFoo(${wrappedComponentName})`;
  return WithFoo;
}

Props 命名 : 防止用 DOM 组件的属性名表白不同的意义
Why? 人们冀望 style、className 这种属性代表一个明确的意义。为应用程序的一个子集扭转此 API 会使代码的可读性升高,维护性升高,并可能导致谬误。

// bad
<MyComponent style="fancy" />

// bad
<MyComponent className="fancy" />

// good
<MyComponent variant="fancy" />

3. 对齐

对 JSX 语法应用这些对齐格调。eslint: react/jsx-closing-bracket-location react/jsx-closing-tag-location

// bad
<Foo superLongParam="bar"
     anotherSuperLongParam="baz" />

// good
<Foo
  superLongParam="bar"
  anotherSuperLongParam="baz"
/>

// 如果能放在一行,也能够用单行示意
<Foo bar="bar" />

// Foo 外面的标签失常缩进
<Foo
  superLongParam="bar"
  anotherSuperLongParam="baz"
>
  <Quux />
</Foo>

// bad
{showButton &&
  <Button />
}

// bad
{
  showButton &&
    <Button />
}

// good
{showButton && (<Button />)}

// good
{showButton && <Button />}

4. 援用

在 JSX 属性中用双引号 (“),然而在 js 里用单引号 (‘)。eslint: jsx-quotes
Why? 失常的 HTML 属性也通常应用双引号而不是单引号,所以 JSX 属性也应用这个约定。

// bad
<Foo bar='bar' />

// good
<Foo bar="bar" />

// bad
<Foo style={{left: "20px"}} />

// good
<Foo style={{left: '20px'}} />

5. 属性

props 用小驼峰

// bad
<Foo
  UserName="hello"
  phone_number={12345678}
/>

// good
<Foo
  userName="hello"
  phoneNumber={12345678}
/>

如果 prop 的值是 true 能够疏忽这个值,间接写 prop 名就能够。eslint: react/jsx-boolean-value

// bad
<Foo
  hidden={true}
/>

// good
<Foo
  hidden
/>

// good
<Foo hidden />

防止用数组下标作为 key 属性,举荐用稳固的 ID
Why? 不应用稳定杆的 ID is an anti-pattern 会对组件性能产生消极影响,并且组件状态容易呈现问题。如果数组元素可能会发生变化,咱们不举荐应用下标作为 key。

// bad
{todos.map((todo, index) =>
  <Todo
    {...todo}
    key={index}
  />
)}

// good
{todos.map(todo => (
  <Todo
    {...todo}
    key={todo.id}
  />
))}

6. 对于 Refs 请勿适度应用

详见 react 官网文档 Refs and the DOM
Refs 转发

7.Hook 规定

只在最顶层应用 Hook

不要在循环,条件或嵌套函数中调用 Hook,确保总是在你的 React 函数的最顶层调用他们。恪守这条规定,你就能确保 Hook 在每一次渲染中都依照同样的程序被调用。这让 React 可能在屡次的 useState 和 useEffect 调用之间放弃 hook 状态的正确。(如果你对此感到好奇,咱们在上面会有更深刻的解释。)

只在 React 函数中调用 Hook

不要在一般的 JavaScript 函数中调用 Hook。你能够:

✅ 在 React 的函数组件中调用 Hook

✅ 在自定义 Hook 中调用其余 Hook

遵循此规定,确保组件的状态逻辑在代码中清晰可见。

8. 状态治理标准

约定:

  1. 当咱们我的项目中复杂程度较低时,倡议只用 state 就能够了
  2. 如果仅仅因为存在多层传递数据的场景,不倡议应用 mobx 或 redux,可应用 context 解决
  3. 如果仅仅因为夸路由数据共享,不倡议应用 mobx 或 redux,可应用 context 或者路由传参解决
  4. 如果业务简单,须要应用第三方状态治理解决复杂度,看下一条
  5. 当我的项目复杂度个别,小规模团队或开发周期较短、要求疾速上线时,举荐应用 mobx
  6. 当我的项目复杂度较高,团队规模较大或要求对事件散发解决可监控可回溯时,举荐应用 redux,可尝试应用 rematch 或 @reduxjs/toolkit,缩小模板代码
  7. 如果后端数据合乎 REST 格调且数据格式对立且反复数据较多,举荐应用扁平化解决数据,参考 normalizr,eg: twitter 知乎

9. 目录构造

├─package-lock.json
├─package.json ------------ // 我的项目配置
├─postcss.config.js ------- // postcss 配置
├─public ------------------ // 公开目录
│ ├─favicon.ico
│ └─index.html
├─README.md ---------- // 我的项目阐明
└─src --------------------- // 源码目录
├─App.tsx --------------- // 根组件
├─assets ---------------- // 动态资源目录
│ └─images -------------- // 图片目录
│     └─logo.png ------ // logo 图片
│ └─svg -------------- // 图标目录
│     └─logo.svg ------ // logo 图片
├─components ------------ // 公共组件目录
│ └─Menu ---------------- // 公共组件
│   ├─index.tsx ---------- // 组件文件
│   └─index.scss ------ // 组件款式
├─constants ---------------- // 我的项目常量
│ └─index.ts
├─libs ------------------ // 第三方库目录
├─index.tsx --------------- // 主入口
├─router ---------------- // 路由配置
│ └─index.tsx
├─store ----------------- // 状态治理
│ ├─module.ts // 模块
│ └─index.ts // 入口
├─tests ----------------- // 测试目录
├─utils ----------------- // 工具目录
│ ├─a.ts
│ └─index.ts
└─pages ----------------- // 视图目录
  └─Home ---------------- // 页面组件
    ├─components -------- // 子组件目录
    │ └─Header
    │   ├─index.tsx
    │   └─index.scss
    └─index.tsx ---------- // 组件主体

10. 所有尽量遵循官网文档

状态晋升 – 多个组件数据变动(遵循原则:依附自上而下的数据流,而不是尝试在不同组件间同步 state)
React 哲学
Effect 应用留神

参考

https://jdf2e.github.io/jdc_f…
https://zh-hans.reactjs.org/d…
https://juejin.cn/post/702392…

正文完
 0