首页 > 其他分享 >前端React框架和jsx语法的编码规范

前端React框架和jsx语法的编码规范

时间:2023-03-31 15:44:27浏览次数:43  
标签:编码 good return render React bad 组件 jsx

基本规则(Basic Rules)

每个文件只包含一个 React 组件

  • 然而,在一个文件里包含多个没有 state 或纯组件是允许的。eslint: react/no-multi-comp.
  • 经常用 JSX 语法。
  • 不要用 React.createElement, 除非你从一个非 JSX 文件中初始化 app。

Class vs React.createClass vs stateless

如果你要用 state refs, 最好用 class extends React.Component 而不是 React.createClass. eslint: react/prefer-es6-class react/prefer-stateless-function

// bad
const Listing = React.createClass({
  // ...
  render() {
    return <div>{this.state.hello}</div>;
  }
});

// good
class Listing extends React.Component {
  // ...
  render() {
    return <div>{this.state.hello}</div>;
  }
}

如果你没有使用 state、 refs ,最好用正常函数(不是箭头函数)也不是 class:

// bad
class Listing extends React.Component {
  render() {
    return <div>{this.props.hello}</div>;
  }
}
// bad (不鼓励依赖函数名推断————relying on function name inference is discouraged)
const Listing = ({ hello }) => (
<div>{hello}</div>
);

// good
function Listing({ hello }) {
  return <div>{hello}</div>;
}

混合(Mixins)

不要用 mixins.

Why? mixins 会引入一些隐含依赖,导致命名冲突,会导致滚雪球式的复杂度。大多数情况下,mixins 都可以通过组件,高阶组件 HOC或者工具模块更好的实现。Why? mixins 会引入一些隐含依赖,导致命名冲突,会导致滚雪球式的复杂度。大多数情况下,mixins 都可以通过组件,高阶组件 HOC或者工具模块更好的实现。

命名(Naming)

扩展名: 用 .jsx 作为组件扩展名。
文件名: 用大驼峰作为文件名,如:ReservationCard.jsx。
参数命名: React 组件用大驼峰,组件的实例用小驼峰。eslint: react/jsx-pascal-case

// 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 可以用于开发者工具或者错误信息中,同时还有一个值可以清晰的表达这种组件关系,这可以帮助人们理解到底发生了什么 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会使代码的可读性降低,维护性降低,并可能导致错误。 Why? 人们期望 style、 className 这种属性代表一个明确的意义。为应用程序的一个子集改变此API会使代码的可读性降低,维护性降低,并可能导致错误。

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

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

声明(Declaration)

不要通过 displayName 命名组件。最好通过引用命名组件。

// bad
export default React.createClass({
 displayName: 'ReservationCard',
 // stuff goes here
});

// good
export default class ReservationCard extends React.Component {

} 

对齐(Alignment)

对 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 />}

引号(Quotes)

在 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' }} />

空格(Spacing)

在自闭和标签内空一格。eslint: no-multi-spaces, react/jsx-tag-spacing

 // bad
<Foo/>
// very bad
<Foo />

// bad
<Foo
/>
// good
<Foo />

JSX 里的大括号不要空格。eslint: react/jsx-curly-spacing

// bad
<Foo bar={ baz } />

// good
<Foo bar={baz} />

属性(Props)

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 />

标签通常会设置 alt 属性。如果图片是表现型的, alt可以是空字符串或者必须有role="presentation" 这个属性。eslint: jsx-a11y/alt-text

// bad
<img src="hello.jpg" />

// good
<img src="hello.jpg" alt="Me waving hello" />

// good
<img src="hello.jpg" alt="" />

// good
<img src="hello.jpg" role="presentation" />

不要在的 alt 属性里用类似 "image", "photo", "picture" 这些单词。eslint: jsx-a11y/img-redundant-alt

Why? 因为屏幕阅读器已经将 img 发音为图片了,所以这个信息就不需要出现在 alt 文本里了。

// bad
<img src="hello.jpg" alt="Picture of me waving hello" />

// good
<img src="hello.jpg" alt="Me waving hello" />

只用可用的,不抽象的 ARIA roles. eslint: jsx-a11y/aria-role

// bad - 不是一个 ARIA role
<div role="datepicker" />

// bad - 抽象的 ARIA role
<div role="range" />

// good
<div role="button" />

不要在元素上用 accessKey。eslint: jsx-a11y/no-access-key

Why? 使用屏幕阅读器和键盘的人使用的键盘快捷键和键盘命令之间的不一致使得可访问性变得复杂。

// bad
<div accessKey="h" />

// good
<div />

避免用数组下标作为 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}
  />
))}

对于所有非必须属性,定义一个明确的默认值。

Why? propTypes 是一个文档形式,同时提供默认属性意味着使用者不需要假定那么多值。另外,这也意味着你的代码可以忽略类型检查。

// bad
function SFC({ foo, bar, children }) {
  return <div>{foo}{bar}{children}</div>;
}
SFC.propTypes = {
  foo: PropTypes.number.isRequired,
  bar: PropTypes.string,
  children: PropTypes.node,
};

// good
function SFC({ foo, bar, children }) {
  return <div>{foo}{bar}{children}</div>;
}
SFC.propTypes = {
  foo: PropTypes.number.isRequired,
  bar: PropTypes.string,
  children: PropTypes.node,
};
SFC.defaultProps = {
  bar: '',
  children: null,
};

少用props扩展运算符,既 {...props}

Why? 除非你更喜欢把不需要的props属性传入组件。而且对于 v15.6.1 及更早以前的 React, 你只能给DOM元素传非HTML属性的props。

例外:
HOC 是代理 props 并且提成了propTypes

function HOC(WrappedComponent) {
  return class Proxy extends React.Component {
    Proxy.propTypes = {
      text: PropTypes.string,
      isLoading: PropTypes.bool
    };

    render() {
      return <WrappedComponent {...this.props} />
    }
  }
}

扩展一个已知的,有明确属性的对象也是可以的。这个对用 Mocha 的 beforeEach 函数做单测时尤其有用。

export default function Foo {
 const props = {
   text: '',
   isPublished: false
 }
 return (<div {...props} />);
}

使用说明:尽可能过滤出不需要的属性。同时用prop-type-exact去帮助避免bug。

// bad
render() {
  const { irrelevantProp, ...relevantProps } = this.props;
  return <WrappedComponent {...this.props} />
}

// good
render() {
  const { irrelevantProp, ...relevantProps } = this.props;
  return <WrappedComponent {...relevantProps} />
}

引用(Refs)

推荐用 ref callback 函数。eslint: react/no-string-refs

// bad
<Foo
  ref="myRef"
/>

// good
<Foo
  ref={(ref) => { this.myRef = ref; }}
/>

括号(Parentheses)

当 JSX 标签有多行时,用圆括号包起来。eslint: react/jsx-wrap-multilines

// bad
render() {
  return <MyComponent variant="long body" foo="bar">
            <MyChild />
          </MyComponent>;
}

// good
render() {

return (
  <MyComponent variant="long body" foo="bar">
    <MyChild />
  </MyComponent>
);
}

// good, 单行可以直接写
render() {
  const body = <div>hello</div>;
  return <MyComponent>{body}</MyComponent>;
} 

标签(Tags)

当没有子元素时,最好用自闭合标签。eslint: react/self-closing-comp

// bad
<Foo variant="stuff"></Foo>

// good
<Foo variant="stuff" />

如果你的组件有多行属性,用他的闭合标签单独作为结束行。eslint: react/jsx-closing-bracket-location

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

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

方法(Methods)

用箭头函数关闭局部变量。

function ItemList(props) {
  return (
    <ul>
      {props.items.map((item, index) => (
        <Item
          key={item.key}
          onClick={() => doSomethingWith(item.name, index)}
        />
      ))}
    </ul>
  );
}

在构造函数里绑定事件处理函数。eslint: react/jsx-no-bind

Why? render 函数中的绑定调用在每次 render 的时候都会创建一个新的函数。

// bad
class extends React.Component {
  onClickDiv() {
  // do stuff
  }
  render() {
    return <div onClick={this.onClickDiv.bind(this)} />;
  }
}

// good
class extends React.Component {
  constructor(props) {
  super(props);
  this.onClickDiv = this.onClickDiv.bind(this);
  }
  onClickDiv() {
  // do stuff
  }
  render() {
    return <div onClick={this.onClickDiv} />;
  }
}

不要在 React 组件里使用下划线作为内部方法名前缀。

Why? 下划线前缀有时候在其他语言里被用于表示私有。但是 JavaScript 原生并不支持私有,所有东西都是公有的。尽管在你的意图里,对你的属性添加下划线前缀不是真的是他变成私有属性,而且任何属性(不论是不是下划线前缀)都被认为是公有的。

// bad
React.createClass({
  _onClickSubmit() {
    // do stuff
  },
  // other stuff
});

// good
class extends React.Component {
  onClickSubmit() {
    // do stuff
  }
  // other stuff
}

确保你的 render 函数有返回值。eslint: react/require-render-return

// bad
render() {
 (<div />);
}

// good
render() {
 return (<div />);
}

排序(Ordering)

class extends React.Component 内部属性的顺序:

  1. 可选的 static 方法
  2. constructor
  3. getChildContext
  4. componentWillMount
  5. componentDidMount
  6. componentWillReceiveProps
  7. shouldComponentUpdate
  8. componentWillUpdate
  9. componentDidUpdate
  10. componentWillUnmount
  11. clickHandlers or eventHandlers 如: onClickSubmit()、 onChangeDescription()
  12. getter methods for render 如: getSelectReason()、 getFooterContent()
  13. optional render methods 如: renderNavigation()、 renderProfilePicture()
  14. render

如何定义 propTypes、 defaultProps、 contextTypes 等...

import React from 'react';
import PropTypes from 'prop-types';

const propTypes = {
  id: PropTypes.number.isRequired,
  url: PropTypes.string.isRequired,
  text: PropTypes.string,
};
const defaultProps = {
  text: 'Hello World',
};
 
class Link extends React.Component {
  static methodsAreOk() {
    return true;
  }
  render() {
    return <a href={this.props.url} data-id={this.props.id}>        {this.props.text}</a>;
    }
  }
Link.propTypes = propTypes;
Link.defaultProps = defaultProps;
export default Link;

React.createClass 内部属性排序:eslint: react/sort-comp

  1. displayName
  2. propTypes
  3. contextTypes
  4. childContextTypes
  5. mixins
  6. statics
  7. defaultProps
  8. getDefaultProps
  9. getInitialState
  10. getChildContext
  11. componentWillMount
  12. componentDidMount
  13. componentWillReceiveProps
  14. shouldComponentUpdate
  15. componentWillUpdate
  16. componentDidUpdate
  17. componentWillUnmount
  18. clickHandlers or eventHandlers 如: onClickSubmit()、 onChangeDescription()
  19. getter methods for render 如: getSelectReason()、 getFooterContent()
  20. optional render methods 如: renderNavigation()、 renderProfilePicture
  21. render

isMounted

不要用 isMounted。eslint: react/no-is-mounted

Why? [isMounted 是反模式][anti-pattern], 这个在 ES6 class 里不允许的,而且即将被官方废弃。

标签:编码,good,return,render,React,bad,组件,jsx
From: https://www.cnblogs.com/CCxi/p/17276487.html

相关文章

  • vue或者react中的hooks的理解
    我们听过react里面有hooks的概念,那么怎么理解hooks呢? 其实vue2中,我们没有hooks的概念,vue3中我们引入了组合式函数(也就是用组合式api写的),它其实就是vue的hooks。 总结下来,hooks有以下特点:1、hooks其实就是个函数,只是实现它的方法比较特殊,利用组合式api实现的。2、组合式函......
  • React 笔记
    Date:2023-03-3020:36:05视频链接:尚硅谷React教程开始学react了,......
  • react useComparedState
    import{useCallback,useRef,useState}from'react';import{shallowEqual}from"../utils/shallowEqual";functionuseComparedState(initialState:any){const[state,setState]=useState(initialState);conststateRef=useRef......
  • React Router 备忘清单_开发速查表分享
    ReactRouter备忘清单IT宝库整理的ReactRouter开发速查清单适合初学者的综合ReactRouter6.x备忘清单入门,为开发人员分享快速参考备忘单。开发速查表大纲入门安装使用添加路由器根路由处理未找到错误contacts用户界面嵌套路由客户端路由创建联......
  • 数字证书编码ASN.1
    一、任务详情参考附件中图书p223中13.2的实验指导,完成DER编码序列号=1174(0x0496),证书签发者DN="CN=VirtualCA,C=CN",证书持有者DN="CN=你的名字拼音,OU=Person,C=CN",证书有效期=20200222000000-20220222000000。用echo-n-e"编码">你的学号.der中,用OpenSSLasn1parse分析......
  • React 编程思想 #1
    React编程思想#1看太多语法,都不如简单尝试一下,跟着官方文档做了一下DEMO,文档写的真不错,就是没翻译完,一大半都还是英文(×_×),本篇其实大部分也是在重复文档内容,不过加上了自己的尝试。从原型开始React可以改变你对所看到的设计以及所构建的应用程序的看法。以前你看到的是......
  • Livestream Broadcaster:整合在线服务的高清视频编码器
    Livestream是一家提供现场视频流服务的创业公司,近日发布了一个价值495美金的视频编码器Broadcaster,几乎能连接任何摄像头,通过WiFi或任何网无线USB调制解调器将高清视频直接......
  • 选择Kendo React PDF查看器的几个理由,一定要看!
    KendoUI致力于新的开发,来满足不断变化的需求,通过React框架的KendoUIJavaScript封装来支持ReactJavascript框架。KendoUIforReact能够为客户提供更好的用户体验,并且......
  • 创建剧本以开始新的编码任务
    您在平台竞标中中标了,或者,您已收到客户的要求。你做的第一件事是什么?有一本剧本很有价值。每次开始研究代码中的新更改时都要遵循的过程。它使您的工作更可预测、更完整......
  • React状态 和 JavaScript箭头函数
    React状态和JavaScript箭头函数在看React的状态时见到了JS的箭头函数,一时间没看明白。React状态React把组件看成是一个状态机(StateMachines)。通过与用户的交互......