• Stars
    star
    157
  • Rank 238,399 (Top 5 %)
  • Language
  • Created almost 9 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A mostly reasonable approach to React and JSX

React 编程规范(by Airbnb)

基本规则

  • 每个文件只包含一个 React 组件
  • 使用 JSX 语法
  • 除非是从一个非 JSX 文件中初始化 app,否则不要使用 React.createElement

Class vs React.createClass

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

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

反之, 则优先使用普通函数(不建议使用箭头函数)。

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

// bad 
const Listing = ({ hello }) => (
  <div>{hello}</div>
);

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

混淆

为什么? Mixins 会增加隐式的依赖,导致命名冲突,并且会以雪球式增加复杂度。在大多数情况下Mixins可以被更好的方法替代,如:组件化,高阶组件,工具模块等。

命名

  • 扩展名: 使用 jsx 作为 React 组件的扩展名
  • 文件名: 文件命名采用帕斯卡命名法,如:ReservationCard.jsx
  • 引用名: 组件引用采用帕斯卡命名法,其实例采用驼峰式命名法。eslint rules: react/jsx-pascal-case
// bad
const reservationCard = require('./ReservationCard');

// good
const ReservationCard = require('./ReservationCard');

// bad
const ReservationItem = <ReservationCard />;

// good
const reservationItem = <ReservationCard />;
  • 组件命名: 使用文件名作为组件名。例如:ReservationCard.jsx 组件的引用名应该是 ReservationCard。然而,对于一个目录的根组件,应该使用 index.jsx 作为文件名,使用目录名作为组件名。
// bad
const Footer = require('./Footer/Footer.jsx')

// bad
const Footer = require('./Footer/index.jsx')

// good
const Footer = require('./Footer')
  • 高阶组件命名: 如果是新生成的模块,其模块名的 displayName 应该为高阶模块名和传入模块名的组合. 例如, 高阶模块 withFoo(), 当传入一个 Bar 模块的时候, 新的模块名 displayName 应该为 withFoo(Bar).

为什么?一个模块的 displayName 可能会在开发者工具或者错误信息中使用到,因此有一个能清楚的表达这层关系的值能帮助我们更好的理解模块发生了什么,更好的Debug.

// 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;
}
  • 属性命名: 避免使用 DOM 属性为组件的属性命名.

为什么?对于 styleclassName 这样的属性名会默认代表一些含义,在你的应用中使用这些属性来表示其他的含义会使你的代码更难阅读,更难维护,并且可能会引起bug。

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

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

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

声明

  • 不要通过 displayName 来命名组件,通过引用来命名组件
// bad
export default React.createClass({
  displayName: 'ReservationCard',
  // stuff goes here
});

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

对齐

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

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

  // if props fit in one line then keep it on the same line
  <Foo bar="bar" />

  // children get indented normally
  <Foo
    superLongParam="bar"
    anotherSuperLongParam="baz"
  >
    <Spazz />
  </Foo>

引号

  • 对于 JSX 使用双引号,对其它所有 JS 属性使用单引号。eslint:jsx-quotes

为什么?因为 JSX 属性不能包含被转移的引号,并且双引号使得如 "don't" 一样的连接词很容易被输入。常规的 HTML 属性也应该使用双引号而不是单引号,JSX 属性反映了这个约定。

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

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

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

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

空格

// bad
<Foo/>

// very bad
<Foo                 />

// bad
<Foo
 />

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

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

属性

  • 属性名采用驼峰式命名法
// bad
<Foo
  UserName="hello"
  phone_number={12345678}
/>

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

// good
<Foo
  hidden
/>

// good
<Foo hidden />
  • img 标签要添加 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" />
  • 不要在 img 标签的 alt 属性中使用 "image", "photo", 或 "picture" 一类的单词。eslint:jsx-a11y/img-redundant-alt

为什么? 屏幕助读器已经将 img 作为图片了,所以没必要再在 alt 属性中进行说明

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

// good
<img src="hello.jpg" alt="Me waving hello" />
// bad - not an ARIA role
<div role="datepicker" />

// bad - abstract ARIA role
<div role="range" />

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

为什么?屏幕助读器在键盘快捷键与键盘命令时造成的不统一性会导致阅读性更加复杂。

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

// good
<div />
  • 避免使用数组的 index 来作为属性 key 的值,推荐使用唯一ID(为什么?)
// bad
{todos.map((todo, index) =>
  <Todo
    {...todo}
    key={index}
  />
)}

// good
{todos.map(todo => (
  <Todo
    {...todo}
    key={todo.id}
  />
))}
  • 对于组件所有的非必要属性需在 defaultProps 中定义。

为什么?propTypes 也是一种文档形式,提供 defaultProps 定义更有利于其他人阅读你的代码,并且能省略一些类型检查

// 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,
};
  • 尽量少用扩展运算符

为什么?除非你很想传递一些不必要的属性。对于React v15.6.1和更早的版本,你可以给DOM传递一些无效的HTML属性

例外情况:

  • 使用了变量提升的高阶组件
function HOC(WrappedComponent) {
  return class Proxy extends React.Component {
    Proxy.propTypes = {
      text: PropTypes.string,
      isLoading: PropTypes.bool
    };

    render() {
      return <WrappedComponent {...this.props} />
    }
  }
}
  • 很清楚扩展运算符是用于对象时。在使用 Mocha 测试组件的时扩展运算符就非常有用
export default function Foo {
  const props = {
    text: '',
    isPublished: false
  }

  return (<div {...props} />);
}    

注意:使用时要尽可能过滤不必要的属性。使用 prop-types-exact能预防 bug。

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

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

Refs

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

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

括号

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

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

  // good, when single line
  render() {
    const body = <div>hello</div>;
    return <MyComponent>{body}</MyComponent>;
  }

标签

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

  // good
  <Foo className="stuff" />
// bad
  <Foo
    bar="bar"
    baz="baz" />

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

方法

  • 使用箭头函数来访问本地变量
function ItemList(props) {
  return (
    <ul>
      {props.items.map((item, index) => (
        <Item
          key={item.key}
          onClick={() => doSomethingWith(item.name, index)}
        />
      ))}
    </ul>
  );
}
  • 在构造函数中绑定需要在 render 方法使用的事件处理函数(绑定 this)。eslint:react/jsx-no-bind

为什么?在组件每次 render 时, 每次 bind 调用都会创建新的函数

// 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 组件的内置方法使用 underscore 前缀

为什么?_ 前缀在某些语言中通常被用来表示私有变量或者函数,但在原生 JavaScript 不支持所谓的私有变量,所有的变量函数都是共有的。在变量名之前加上下划线并不会使这些变量私有化,并且所有的属性都应该被视为是共有的。相关 issue:#1024 / #490

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

  // other stuff
});

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

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

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

顺序

  • 继承 React.Component 的类的方法遵循下面的顺序
  1. constructor
  2. optional static methods
  3. getChildContext
  4. componentWillMount
  5. componentDidMount
  6. componentWillReceiveProps
  7. shouldComponentUpdate
  8. componentWillUpdate
  9. componentDidUpdate
  10. componentWillUnmount
  11. clickHandlers or eventHandlers like onClickSubmit() or onChangeDescription()
  12. getter methods for render like getSelectReason() or getFooterContent()
  13. Optional render methods like renderNavigation() or renderProfilePicture()
  14. render
  • 怎么定义 propTypes,defaultProps,contextTypes 等等...
import React, { PropTypes } from 'react';

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 时,方法顺序如下:
  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 like onClickSubmit() or onChangeDescription()
  19. getter methods for render like getSelectReason() or getFooterContent()
  20. Optional render methods like renderNavigation() or renderProfilePicture()
  21. render

eslint: react/sort-comp

isMounted

为什么?isMounted 是一种反模式,在 ES6 classes 中不可用。官方未来将会删除改属性。·

Related Resource

·

More Repositories

1

blog

🐶 👏 🌟 Welcome to star
JavaScript
3,782
star
2

front-end-handbook

Front-end Developer HandBook. Read online: https://dwqs.gitbooks.io/frontenddevhandbook/content/
CSS
605
star
3

area-data

中国省市区数据(含港澳台)
JavaScript
482
star
4

vue-area-linkage

省市区联动选择: https://dwqs.github.io/vue-area-linkage/
Vue
477
star
5

vue-to-react

🛠️ 👉 Try to transform Vue component to React component
JavaScript
431
star
6

area-puppeteer

基于 puppeteer 的中国行政区域抓取爬虫
JavaScript
169
star
7

vue-mobx

😄 ⭐ 😇 Mobx binding for Vuejs 2.
TypeScript
110
star
8

v2-table

A simple table component based Vue 2.x: https://dwqs.github.io/v2-table/
Vue
100
star
9

js2excel

😌 😃 👿 A simple module for excel and json converts each other, which works in the browser.
TypeScript
99
star
10

v2-datepicker

A simple datepicker component based Vue 2.x: https://dwqs.github.io/v2-datepicker/
JavaScript
90
star
11

tech-read

Grab tech articles daily from UGC communities
JavaScript
77
star
12

react-native-image-viewer

A pure JavaScript image viewer component for react-native apps with pan, pinch.etc, supporting both iOS and Android.
JavaScript
67
star
13

codewars-practices

Some best practices for practice questions on codewars, update it weekly
67
star
14

react-area-linkage

省市区联动选择: https://dwqs.github.io/react-area-linkage/
JavaScript
61
star
15

react-virtual-list

A tiny virtualization list component(gzipped 6KB), supports dynamic height: https://dwqs.github.io/react-virtual-list/
JavaScript
46
star
16

vue-startup

A template with webpack 4 + vuejs 2 + + babel 7 setup for projects startup
JavaScript
43
star
17

chare

A simple CLI scaffolding for front-end projects
JavaScript
35
star
18

vue-resume

A Personal Resume Template is powered by Vue,Node.js & Webpack:http://resume.ido321.com
Vue
34
star
19

react-demos

Some react demos for myself: https://dwqs.github.io/react-demos
JavaScript
33
star
20

node-style-guide

A guide for styling your node.js / JavaScript code.
32
star
21

v2-lazy-list

A simple lazy-load list component based Vue 2.x: https://dwqs.github.io/v2-lazy-list/
JavaScript
31
star
22

mp-jithub

Mini program for Github
Vue
30
star
23

vue-typescript

A template with webpack 4 + vuejs 2 + typescript 2 setup for projects startup
TypeScript
27
star
24

revuejs

🐇 A tiny, light and handy state management for vuejs 2, writing less verbose code.
JavaScript
24
star
25

vue-toast

A toast component written with Vue, designed based on Ant Design [deprecated]
Vue
18
star
26

webpack-mpvue-startup

A template with webpack 3 + mpvue 1 setup for projects startup
JavaScript
14
star
27

beautify-scrollbar

Beautify browser's scrollbars: https://dwqs.github.io/beautify-scrollbar/index
JavaScript
13
star
28

lue

🌱 Vue and vuex based library, writing less verbose code.
JavaScript
12
star
29

mpvue-markdown-parser

A markdown parser for mpvue
JavaScript
9
star
30

nx

A hexo theme based on landscape-plus
CSS
9
star
31

babel-plugin-on-demand-import

Babel plugin for importing components on demand
JavaScript
9
star
32

react-startup

A template with webpack 4 + react 16 + react-router 4 + babel 7 setup for projects startup
JavaScript
8
star
33

chrome-extension-for-wiki

🐔 🐮 🐼 Add awesome article link to your wiki repo on github quickly./快速添加文章链接到 wiki repo 的 chrome 扩展
JavaScript
7
star
34

async-await-error-handling

Error handling friendly for async/await in ts and js
JavaScript
7
star
35

reproto

A tool for generate simple random password which contains letters, number and special characters
JavaScript
6
star
36

icons

Some interesting icon & design implemented by pure css.
5
star
37

orbithub

A chrome extensition for convenient github search
JavaScript
5
star
38

redux-actions-promise

🐰 🐱 🐻 FSA-compliant promise middleware for Redux, supports referencing dispatcher/state in action.
TypeScript
5
star
39

maoxuan

教员选集阅读笔记
5
star
40

tiny-dom-helpers

🌜 🌚 🌛 Tiny dom helpers, supports IE9 +.
JavaScript
5
star
41

scroll-on-webview

处理 webview 上的滚动
JavaScript
4
star
42

infine

A chrome extension for theme color replacement of Github
CSS
4
star
43

note

Personal note sites, write what you want, support markdown: http://note.ido321.com/
JavaScript
3
star
44

view-star-packages-on-npm

View your star packages on npmjs.com: https://dwqs.github.io/view-star-packages-on-npm
JavaScript
3
star
45

async-react-compoment

😎 👀 🙈 Async component loaded based webpack 3 for react-router 4.[unmaintained]
TypeScript
2
star
46

gitlang

Repository to list all programming languages github supports
JavaScript
2
star